2015-12-22 39 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