从1页模板生成iTextSharp高效批量Pdf

我使用ITextSharp生成多页PDF,每个页面都有相同的模板。

问题是PDF按照模板的大小以Phisical Size增长。

我必须使用ACROFIELDS

如何减小最终文件大小?

这是pdf处理程序的代码片段:

public void ProcessRequest(HttpContext context) { Context = context; Response = context.Response; Request = context.Request; try { LoadDataInternal(); } catch (System.Threading.ThreadAbortException) { // no-op } catch (Exception ex) { Logger.LogError(ex); Response.Write("Error"); Response.End(); } Response.BufferOutput = true; Response.ClearHeaders(); Response.ContentType = "application/pdf"; if (true) { Response.AddHeader("Content-Disposition", "attachment; filename=" + (string.IsNullOrEmpty(DownloadFileName) ? context.Session.SessionID + ".pdf" : DownloadFileName)); } PdfCopyFields copy = new PdfCopyFields(Response.OutputStream); // add a document for (int i = 0; i < dataset.Tables["Model"].Rows.Count; i++) { copy.AddDocument(new PdfReader(renameFieldsIn(TemplatePath, i))); // add a document } copy.SetFullCompression(); // Close the PdfCopyFields object copy.Close(); } private byte[] renameFieldsIn(String datasheet, int i) { MemoryStream baos = new MemoryStream(); // Create the stamper PdfStamper stamper = new PdfStamper(new PdfReader(GetTemplateBytes()), baos); // Get the fields AcroFields form = stamper.AcroFields; // Loop over the fields List keys = new List(form.Fields.Keys); foreach (var key in keys) { // rename the fields form.RenameField(key, String.Format("{0}_{1}", key, i)); } stamper.FormFlattening = true; stamper.FreeTextFlattening = true; stamper.SetFullCompression(); SetFieldsInternal(form, i); // close the stamper stamper.Close(); return baos.ToArray(); } protected byte[] GetTemplateBytes() { var data = Context.Cache[PdfTemplateCacheKey] as byte[]; if (data == null) { data = File.ReadAllBytes(Context.Server.MapPath(TemplatePath)); Context.Cache.Insert(PdfTemplateCacheKey, data, null, DateTime.Now.Add(PdfTemplateCacheDuration), Cache.NoSlidingExpiration); } return data; } 

我之前做过一些类似的事情,发现在组合所有页面之后,再次通过PDFStamper运行整个生成的文档会导致文件大小的明显压缩。

好的,我的一个朋友想出了一个解决方案。 剩下的唯一问题是创建新的PdfStamper所需的内存量。 所以这是重写的程序。

无论如何。 希望这能扼杀任何其他人。 如果你有更好的解决方案,请不要害羞。

 public void ProcessRequest (HttpContext context) { var watch = System.Diagnostics.Stopwatch.StartNew(); Context = context; Response = context.Response; Request = context.Request; Response.BufferOutput = true; Response.ClearHeaders(); Response.ContentType = "application/pdf"; Response.AddHeader("Content-Disposition", "attachment; filename=itextsharp_multiple.pdf"); var pageBytes = (byte[])null; var pagesAll = new List(); try { for (int i = 0; i < GlobalHttpApplication.Model.TestData.Rows.Count; i++) { PdfStamper pst = null; MemoryStream mstr = null; using (mstr = new MemoryStream()) { try { PdfReader reader = new PdfReader(GetTemplateBytes()); pst = new PdfStamper(reader, mstr); var acroFields = pst.AcroFields; SetFieldsInternal(acroFields, 0); pst.FormFlattening = true; pst.SetFullCompression(); } finally { if (pst != null) pst.Close(); } } pageBytes = mstr.ToArray(); pagesAll.Add(pageBytes); } } finally { } Document doc = new Document(PageSize.A4); var writer = PdfWriter.GetInstance(doc, Response.OutputStream); var copy2 = new PdfSmartCopy(doc, Response.OutputStream); doc.Open(); doc.OpenDocument(); foreach (var b in pagesAll) { doc.NewPage(); copy2.AddPage(copy2.GetImportedPage(new PdfReader(b), 1)); } copy2.Close(); watch.Stop(); File.AppendAllText(context.Server.MapPath("~/App_Data/log.txt"), watch.Elapsed + Environment.NewLine); }