从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); }
- 在按钮点击事件中查找asp:repeater中的Control
- ITextSharp解析带有图像的HTML:它正确解析但不会显示图像
- 为什么MVC无国籍 – 如何解释?
- System.MethodAccessException:尝试通过安全透明方法访问安全性关键方法在所有应用程序上失败
- ASP.NET异步标签更新
- 无法使用Headers =“application / x-www-form-urlencoded”编码我的JSON对象insdie我的WebClient UploadString
- 如何将查询字符串参数转换为asp.net mvc 4中的路由
- System.ArgumentException:参数无效
- 如何在C#ASP.Net Sesssion中保存对象数组?