簡體   English   中英

帶HTML字符串C#的iTextSharp PDF標頭

[英]iTextSharp PDF header with HTML string C#

我正在嘗試使用iTextSharp以及客戶信息,頁眉和頁腳等生成PDF報告。所有這些報告已經使用EVO API生成。 作為遷移過程的一部分,我們計划使用iTextSharp API生成這些報告。

我需要知道是否有可能為iTextSharp PDF標頭提供准備好呈現HTML字符串的功能(現有的EVO設計接受HTML字符串並構建PDF),而不是使用PageEvents來設計PDFPTable和PDFPCell(因為報告的數量是龐大並避免返工)

我需要知道是否有可能為iTextSharp PDF標頭提供現成的HTML字符串渲染(現有的EVO設計接受HTML字符串並生成PDF),而不是使用PageEvents來設計PDFPTable和PDFPCell

您將必須使用頁面事件來繪制頁眉或頁腳,但無需在PdfPTable顯式使用PdfPTable 實際上,您可以在頁面事件期間呈現html,例如:

[Test]
public void CreatePdfWithHtmlHeader()
{
    string htmlHeader = "<!DOCTYPE html><html><body><table style=\"width: 100%; border: 1px solid black;\"><tr><td>A</td><td>B</td></tr></table></body></html>";

    using (FileStream output = new FileStream(@"C:\Temp\test-results\content\html-header.pdf", FileMode.Create, FileAccess.Write))
    using (Document document = new Document(PageSize.A4))
    {
        PdfWriter writer = PdfWriter.GetInstance(document, output);
        writer.PageEvent = new HtmlPageEventHelper(htmlHeader);
        document.Open();
        document.Add(new Paragraph("1"));
        document.NewPage();
        document.Add(new Paragraph("2"));
    }
}

使用以下兩個小幫助程序類。

HtmlPageEventHelper是一個頁面事件偵聽器,它將給定的html代碼片段繪制到頁面標題中。 顯然,它可以替代或附加地寫入頁面頁腳,只需使用適當的列坐標

public class HtmlPageEventHelper : PdfPageEventHelper
{
    public HtmlPageEventHelper(string html)
    {
        this.html = html;
    }

    public override void OnEndPage(PdfWriter writer, Document document)
    {
        base.OnEndPage(writer, document);

        ColumnText ct = new ColumnText(writer.DirectContent);
        XMLWorkerHelper.GetInstance().ParseXHtml(new ColumnTextElementHandler(ct), new StringReader(html));
        ct.SetSimpleColumn(document.Left, document.Top, document.Right, document.GetTop(-20), 10, Element.ALIGN_MIDDLE);
        ct.Go();
    }

    string html = null;
}

對於更復雜的HTML代碼段,您可能希望用@Skary的答案中所示的自定義解析器調用替換XMLWorkerHelper.GetInstance().ParseXHtml調用。

ColumnTextElementHandlerIElementHandler實現,它將內容(例如,通過解析HTML生成)添加到ColumnText

public class ColumnTextElementHandler : IElementHandler
{
    public ColumnTextElementHandler(ColumnText ct)
    {
        this.ct = ct;
    }

    ColumnText ct = null;

    public void Add(IWritable w)
    {
        if (w is WritableElement)
        {
            foreach (IElement e in ((WritableElement)w).Elements())
            {
                ct.AddElement(e);
            }
        }
    }
}

順便說一句,上面的測試產生了具有以下內容的PDF:

第1頁

...

第2頁

...


免責聲明:我主要使用Java,並且以前沒有使用過XmlWorker 因此,該代碼可能具有很大的改進潛力。

我不確定您是否理解正確。

如果您問如何使用iTextSharp將HTML解析為PDF,這是我前一段時間發現的解決方案:

        using (Document document = new Document(size))
        {
            var writer = PdfWriter.GetInstance(document, stream);

            document.Open();
            document.NewPage();
            document.Add(new Chunk(""));

            var tagProcessors = (DefaultTagProcessorFactory)Tags.GetHtmlTagProcessorFactory();
            tagProcessors.RemoveProcessor(HTML.Tag.IMG);
            tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor());

            var charset = Encoding.UTF8;

            CssFilesImpl cssFiles = new CssFilesImpl();
            cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS());
            var cssResolver = new StyleAttrCSSResolver(cssFiles);
            cssResolver.AddCss(srcCssData, "utf-8", true);

            var hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
            hpc.SetAcceptUnknown(true).AutoBookmark(true).SetTagFactory(tagProcessors);
            var htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
            var pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
            var worker = new XMLWorker(pipeline, true);
            var xmlParser = new XMLParser(true, worker, charset);

            xmlParser.Parse(new StringReader(srcFileData));

            document.Close();
        }

為了使其正常工作,您需要在converte函數上方提供的HTML中添加自定義圖像處理器以內聯圖像:

public class CustomImageTagProcessor : iTextSharp.tool.xml.html.Image
{
    public override IList<IElement> End(IWorkerContext ctx, Tag tag, IList<IElement> currentContent)
    {
        IDictionary<string, string> attributes = tag.Attributes;
        string src;
        if (!attributes.TryGetValue(HTML.Attribute.SRC, out src))
            return new List<IElement>(1);

        if (string.IsNullOrEmpty(src))
            return new List<IElement>(1);

        if (src.StartsWith("data:image/", StringComparison.InvariantCultureIgnoreCase))
        {
            // data:[<MIME-type>][;charset=<encoding>][;base64],<data>
            var base64Data = src.Substring(src.IndexOf(",") + 1);
            var imagedata = Convert.FromBase64String(base64Data);
            var image = iTextSharp.text.Image.GetInstance(imagedata);

            var list = new List<IElement>();
            var htmlPipelineContext = GetHtmlPipelineContext(ctx);
            list.Add(GetCssAppliers().Apply(new Chunk((iTextSharp.text.Image)GetCssAppliers().Apply(image, tag, htmlPipelineContext), 0, 0, true), tag, htmlPipelineContext));
            return list;
        }
        else
        {
            return base.End(ctx, tag, currentContent);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM