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

试试这个代码:

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 回答
2

查看Page Events,特别是onStartPage和/或onEndPage以确定您是否必须更改文档的边距。

请注意,这些示例适用于 Java 版本,但转换为 iTextSharp 应该很简单。

于 2012-05-11T15:53:26.170 回答
0

Visual Basic 中的示例代码段

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 回答