我正在使用的应用程序使用itextsharp库从html文件生成pdf报告。显然,当生成大表时,itextsharp会分配大量内存(对于200KB文件,大约300 MB)。 这个问题的解决方案是将表一点一点地添加到文档中(因此表中的所有现有数据都将被刷新),如以下链接所述:
问题:从现有的html文件生成pdf时,如何逐步添加pdfptable?
这是我的代码:
public byte[] GetReportPdf(string template, string cssString)
{
byte[] result;
using (var stream = new MemoryStream())
{
using (
var doc = new Document(
this.Settings.Size,
this.Settings.Margins.Left,
this.Settings.Margins.Right,
this.Settings.Margins.Top,
this.Settings.Margins.Bottom))
{
using (var writer = PdfWriter.GetInstance(doc, stream))
{
// adding the page event, or null
writer.PageEvent = this.Settings.PageEvent;
doc.Open();
// CSS
var cssResolver = new StyleAttrCSSResolver();
using (var cssStream = new MemoryStream(Encoding.UTF8.GetBytes(cssString)))
{
var cssFile = XMLWorkerHelper.GetCSS(cssStream);
cssResolver.AddCss(cssFile);
}
// HTML
var fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
var cssAppliers = new CssAppliersImpl(fontProvider);
var htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
// pipelines
var pdf = new PdfWriterPipeline(doc, writer);
var html = new HtmlPipeline(htmlContext, pdf);
var css = new CssResolverPipeline(cssResolver, html);
// XML worker
var worker = new XMLWorker(css, true);
var parser = new XMLParser(worker);
using (var stringReader = new StringReader(template))
{
parser.Parse(stringReader);
}
doc.Close();
}
}
result = stream.ToArray();
}
return result;
备注:
var tagFactory = Tags.GetHtmlTagProcessorFactory();
tagFactory.AddProcessor(new TableTagProcessor(doc), new string[]{"table"});
public class TableTagProcessor : iTextSharp.tool.xml.html.table.Table{
public override IList<IElement> Start(IWorkerContext ctx, Tag tag)
{
var result = base.Start(ctx, tag);
foreach (PdfPTable table in result.OfType<PdfPTable>())
{
table.Complete = false;
}
return result;
}
public override IList<IElement> End(IWorkerContext ctx, Tag tag, IList<IElement> currentContent)
{
var result = base.End(ctx, tag, currentContent);
foreach (PdfPTable table in result.OfType<PdfPTable>())
{
table.Complete = true;
}
return result;
}}