Itextsharp - 检查添加元素是否会创建新页面

时间:2012-05-11 15:45:11

标签: c# html pdf itextsharp

我正在使用ITextSharp将HTML文档转换为PDF。我使用HTMLWorker.ParseToList并依次循环遍历每个项目。这很好,但是第一页要求后续页面具有不同的边距大小。我可以通过调用MyDocument.NewPage()并调用MyDocument.SetMargins()来完成此任务。

尝试检测页面转换时出现问题。

我可以使用循环来跟踪页面转换,然后调用NewPage()并重置边距,但是,只有在我实际添加了一个包装到新页面的段落时才会发生这种情况,只留下一个几乎是白色的整个页面-space。

如果我添加某个Paragraph对象,我需要一种预先检测页面是否会改变的方法。 我已经尝试使用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页结束之前没有检测到分页符。这是不好的。

我发现让它工作的唯一方法是HALF进入simulation.SetSimpleColumn的高度。

它有效,但我不知道为什么,老实说,这不好。如果有人能给我任何有用的见解。

<小时/>
感谢Alexis我已经解决了。 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);
        }

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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();
        }
    }
}

答案 2 :(得分: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