3

ITextSharpを使用してHTMLドキュメントをPDFに変換しています。HTMLWorker.ParseToListを使用して、各アイテムを順番にループします。これは問題なく機能しますが、最初のページは後続のページとは異なる余白サイズを持つ必要があります。これを行うには、MyDocument.NewPage()を呼び出してMyDocument.SetMargins()を呼び出します。

ページの遷移を検出しようとすると、問題が発生します。

ループを使用してページ遷移を追跡し、NewPage()を呼び出して余白をリセットできますが、これは、新しいページに折り返す段落を実際に追加して、ページ全体を実質的に白のままにした場合にのみ発生します。 -スペース。

特定の段落オブジェクトを追加した場合にページが変更されるかどうかを事前に検出する方法が必要です。ColumnText.Go(true)を使用してシミュレートしようとしました(その結果がColumnText.NO_MORE_COLUMNの場合は、ページ分割にします)。残念ながら、これはせいぜい不安定に見え、ページ分割を検出する傾向があります。完全に間違った場所。

これが私の現在のコードです:

            ColumnText simulation = new ColumnText(Writer.DirectContent);
            simulation.SetSimpleColumn(Writer.PageSize);   
            bool FirstPage = true;
            foreach (var item in ItemList)
            {
                var para = new Paragraph("", Normal);
                para.AddAll(item.Chunks);                    
                para.SpacingAfter = 10;
                foreach (Chunk c in item.Chunks)
                {
                    simulation.AddText(c);
                }
                if(FirstPage) {
                    int simresult = simulation.Go(true);
                    if(simresult == (int)ColumnText.NO_MORE_COLUMN)
                    {
                        textDocument.SetMargins(100,100,100,100);
                        textDocument.NewPage();    
                        FirstPage = false;                 
                    }
                }

                textDocument.Add(para);
            }

その結果、2ページ目の終わりまでページ分割が検出されません。これは良くありません。

それを機能させるために私が見つけた唯一の方法は、simulation.SetSimpleColumnに入る高さを半分にすることです。

それは機能しますが、理由はわかりません。正直なところ、それは良くありません。誰かが私に素晴らしい洞察を与えることができれば。



アレクシスのおかげで私はそれを解決しました。ITextSharpはJavaイベントモデルに完全に準拠しています。これは、WriterとDocumentで直接イベントを探していたので面倒です。まず、PdfPageEventHelperを無効にするクラスを作成する必要がありました。

internal class MainTextEventsHandler : PdfPageEventHelper
{
    public override void OnStartPage(PdfWriter writer, Document document)
    {
        document.SetMargins(document.LeftMargin, document.LeftMargin, document.TopMargin, document.BottomMargin); //Mirror the horizontal margins
        document.NewPage(); //do this otherwise the margins won't take
    }
}

次に、WriterオブジェクトのPageEventプロパティを設定し、ループを変更してシミュレーションを削除しました。

        Writer.PageEvent = new MainTextEventsHandler();
        foreach (var item in ItemList)
        {
            var para = new Paragraph("", Normal);
            para.AddAll(item.Chunks);
            /* per-paragraph stuff here */
            para.SpacingAfter = 10;                    
            textDocument.Add(para);
        }
4

3 に答える 3

2

ページイベント、特にonStartPageonEndPageを見て、ドキュメントの余白を変更する必要があるかどうかを判断してください。

これらの例はJavaバージョン用ですが、iTextSharpへの変換は簡単である必要があることに注意してください。

于 2012-05-11T15:53:26.170 に答える
2

このコードを試してください:

public const string pageBreakHtmlMarker = "<!-- pageBreak -->";
public MemoryStream htmlToPdf(string html)
{
    MemoryStream msOutput = new MemoryStream();
    string[] sep = new string[] { pageBreakHtmlMarker };
    string[] arrHtml = html.Split(sep, 9999, StringSplitOptions.RemoveEmptyEntries);
    htmlToPdf(arrHtml, ref msOutput);
    return msOutput;
}
private void htmlToPdf(string[] arrHtmlPages, ref MemoryStream msOutput)
{
    using (Document document = new Document(PageSize.A4, 30, 30, 30, 30))
    {
        using (HTMLWorker worker = new HTMLWorker(document))
        {
            PdfWriter writer = PdfWriter.GetInstance(document, msOutput); // writer to listen doc ad direct a XML-stream to a file            
            document.Open();
            worker.StartDocument();
            foreach (string html in arrHtmlPages)
            {
                TextReader reader = new StringReader(html); // parse the html into the document
                worker.Parse(reader);
                document.Add(Chunk.NEXTPAGE);
            }
            worker.EndDocument();
        }
    }
}
于 2012-07-18T14:30:16.687 に答える
0

VisualBasicのサンプルスニペット

使用するだけでLoadPage

Dim pdfPageEvents As pdfPageEvents = New pdfPageEvents
writer = PdfWriter.GetInstance(doc, memMemoryStream)
writer.CloseStream = False
writer.PageEvent = pdfPageEvents
doc.Open()

このクラスを同じファイルまたは名前空間に配置します

Public Class pdfPageEvents
    Inherits iTextSharp.text.pdf.PdfPageEventHelper
    Private _strTitle As String, _strPrintFeatures As String

    Public Sub New(ByVal Title As String, ByVal PrintFeatures As String)
        _strTitle = Title
        _strPrintFeatures = PrintFeatures
    End Sub

    Public Overrides Sub OnStartPage(ByVal writer As PdfWriter, ByVal doc As Document)
        If InStr(_strPrintFeatures, "header") > 0 Then
            Dim fntFont As Font = FontFactory.GetFont("Tahoma", BaseFont.CP1250, True, 10, Font.NORMAL, New BaseColor(128, 128, 128))
            Dim imgImage As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(HttpContext.Current.Server.MapPath("../LocalResources/Images/print_company_logo_medium.png"))
            Dim tblTable As New PdfPTable(2)
            Dim celRightCell As PdfPCell

            tblTable.WidthPercentage = 100
            tblTable.HorizontalAlignment = Element.ALIGN_CENTER
            imgImage.ScalePercent(70)

            Dim celLeftCell As New PdfPCell(New Phrase(_strTitle, fntFont))
            celLeftCell.HorizontalAlignment = Element.ALIGN_LEFT
            celLeftCell.Border = 0
            celLeftCell.BorderWidthBottom = 0.5
            celLeftCell.BorderColorBottom = New BaseColor(128, 128, 128)
            celLeftCell.VerticalAlignment = Element.ALIGN_BOTTOM
            celLeftCell.PaddingBottom = 3
            tblTable.AddCell(celLeftCell)

            If InStr(_strPrintFeatures, "logo") > 0 Then
                celRightCell = New PdfPCell(imgImage)
            Else
                celRightCell = New PdfPCell(New Paragraph(""))
            End If

            celRightCell.HorizontalAlignment = Element.ALIGN_RIGHT
            celRightCell.Border = 0
            celRightCell.BorderWidthBottom = 0.5
            celRightCell.BorderColorBottom = New BaseColor(128, 128, 128)
            celRightCell.VerticalAlignment = Element.ALIGN_BOTTOM
            celRightCell.PaddingBottom = 3
            tblTable.AddCell(celRightCell)

            doc.Add(tblTable)
            doc.Add(New Paragraph(vbNewLine))
        End If
    End Sub

    Public Overrides Sub OnEndPage(ByVal writer As PdfWriter, ByVal doc As Document)
        If InStr(_strPrintFeatures, "footer") > 0 Then
            Dim fntFont As Font = FontFactory.GetFont("Tahoma", BaseFont.CP1250, True, 10, Font.NORMAL, New BaseColor(128, 128, 128))
            Dim tblTable As New PdfPTable(2)
            Dim strDate As String = IIf(InStr(_strPrintFeatures, "date") > 0, FormatDateTime(Date.Today, DateFormat.GeneralDate), "")

            tblTable.TotalWidth = doc.PageSize.Width - doc.LeftMargin - doc.RightMargin
            tblTable.HorizontalAlignment = Element.ALIGN_CENTER

            Dim celLeftCell As New PdfPCell(New Phrase(strDate, fntFont))
            celLeftCell.HorizontalAlignment = Element.ALIGN_LEFT
            celLeftCell.Border = 0
            celLeftCell.BorderWidthTop = 0.5
            celLeftCell.BorderColorTop = New BaseColor(128, 128, 128)
            celLeftCell.VerticalAlignment = Element.ALIGN_BOTTOM
            tblTable.AddCell(celLeftCell)

            Dim celRightCell As New PdfPCell(New Phrase(CStr(doc.PageNumber), fntFont))
            celRightCell.HorizontalAlignment = Element.ALIGN_RIGHT
            celRightCell.Border = 0
            celRightCell.BorderWidthTop = 0.5
            celRightCell.BorderColorTop = New BaseColor(128, 128, 128)
            celRightCell.VerticalAlignment = Element.ALIGN_BOTTOM
            tblTable.AddCell(celRightCell)
            tblTable.WriteSelectedRows(0, -1, doc.LeftMargin, (doc.BottomMargin), writer.DirectContent)
        End If
    End Sub
End Class
于 2012-08-23T01:19:31.393 に答える