2015-12-22 46 views
1

我試圖使用iTextSharp與客戶信息,頁眉和頁腳等生成PDF報告。所有這些報告已經生成使用EVO API。作爲遷移過程的一部分,我們計劃使用iTextSharp API生成這些報告。iTextSharp PDF頭與HTML字符串C#

我需要知道是否有任何可能性提供一個準備呈現HTML字符串到iTextSharp PDF頭(現有的EVO設計接受HTML字符串和構建PDF),而不是使用PDFPable和PDFPCell設計PageEvents(作爲報告數量巨大,以避免返工)

+0

如果答案能夠充分回答您在此處發佈的問題,則應考慮接受答案(單擊答案左上方的打勾)。如果沒有,你應該添加一個評論,你在哪個評論中沒有這樣做。 – mkl

回答

2

我需要知道是否有任何可能提供準備渲染HTML字符串iTextSharp的PDF頭(現有EVO設計接受HTML字符串和構建PDF ),而不是使用PageEvents與PDFPTable和PDFPCell

設計你將不得不使用頁面事件繪製頁眉或頁腳,但沒有必要使用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 sniplet繪製到頁眉中。很明顯,它可以替代地或額外寫入頁腳,只需要用相應的列座標

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; 
} 

對於您可能希望通過定製的解析器調用,如@提出Skary的回答來替換XMLWorkerHelper.GetInstance().ParseXHtml通話更復雜的HTML sniplets。

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與此內容:

page 1

...

page 2

...


聲明:我主要是與Java工作和XmlWorker之前沒有使用過。因此,這個代碼可能有很大的改進潛力。

+0

感謝您的詳細回覆。另一個解釋是,iTextSharp HTML to PDF轉換支持在控制級別嗎?防爆。文本框,HTML中的按鈕,它會轉換爲PDF?在我的情況下,轉換後,控件不會顯示在PDF – Sam

+0

正如我的免責聲明中所述,我之前沒有使用'XmlWorker'。因此,我不是iText的HTML支持程度的好來源,並且假設你最好使這個問題成爲一個明確的新的計算器問題。但我知道,在這裏飛過的其他問題,它的支持很容易擴展,參見。 @ Skary的答案中的CustomImageTagProcessor。如果某些元素尚未實現,則可以簡單地添加適當的實現。 – mkl

1

我不知道你的問題是否理解正確。

如果你問如何在這裏使用iTextSharp的解析HTML到PDF是solutin,我發現時間前:

 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(); 
     } 

得到它的工作,你需要自定義圖像處理器添加到內嵌圖像的HTML你提供THA上述轉換器具功能:

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); 
     } 
    } 
} 
+0

當前的EVO API接受不同的參數,例如頭爲HTML字符串,正文/內容爲html字符串,頁腳爲HTML字符串。最後,使用「PrepareRenderPdfPageEvent」,它合併並構建完整的PDF模板。 使用iTextSharp,我已經使用XMLParser將正文HTML字符串解析爲PDF。有沒有什麼辦法以同樣的方式解析頭部HTML字符串爲PDF頭部? – Sam

+0

@Sam你能否給我提供一個例子,說明你將從HTML標題中添加到PDF標題中的內容? – Skary

+1

@Skary很好的使用自定義標籤處理器。它可能會解決一個或兩個尚未解決的數據URL和iText問題(夏普)。 – mkl