来自预定义模板的多页PDF文档
我需要使用一些预定义的公司模板生成PDF格式的发票报告。 我可以使用iTextSharp创建/生成SINGLE PAGE PDF报告。
问题:当发票声明跨越多个页面时出现问题。 我无法将报告(发票声明)扩展到下一页(第二页)。 如果所有数据都不能容纳在一个页面上,则应该在第二页上写入,同时仍然使用公司模板。
模板位于以下路径:
HostingEnvironment.MapPath("~/Content/InvoiceTemplate/invoiceTemplate.pdf")
我正在使用iTextSharp库来创建文档。 以下是用于生成PDF的代码:
public class pdfStatementController : Controller { Models.DYNAMICS_EXTEntities _db = new Models.DYNAMICS_EXTEntities(); // // GET: /pdfStatement/ public ActionResult SendPdfStatement(string InvoiceNumber) { try { InvoiceNumber = InvoiceNumber.Trim(); ObjectParameter[] parameters = new ObjectParameter[1]; parameters[0] = new ObjectParameter("InvoiceNumber", InvoiceNumber); List statementList = new List(); statementList = _db.ExecuteFunction("uspInvoiceStatement", parameters).ToList(); pdfStatementController.WriteInTemplate(statementList); return RedirectToAction("Invoice", "Invoice", new { id = statementList.FirstOrDefault().Customer_ID.ToString().Trim() }); } catch (Exception e) { return View("Error"); } } public static void WriteInTemplate(List statementList) { string invoiceNumber = statementList.FirstOrDefault().Invoice.ToString().Trim(); string month = null; string day = null; string year = null; PdfReader pdfReader = new PdfReader( HostingEnvironment.MapPath( "~/Content/InvoiceTemplate/invoiceTemplate.pdf")); FileStream fileStream = new FileStream( HostingEnvironment.MapPath( "~/Content/reports/" + invoiceNumber + ".pdf"), FileMode.Create); PdfStamper pdfStamper = new PdfStamper(pdfReader, fileStream); AcroFields pdfFields = pdfStamper.AcroFields; pdfFields.SetField("BillToCompany", statementList.FirstOrDefault().BillToCompany.ToString().Trim().ToUpper()); pdfFields.SetField("BillToContact", statementList.FirstOrDefault().BillToContact.ToString().Trim().ToUpper()); pdfFields.SetField("CustomerId", statementList.FirstOrDefault().Customer_ID); pdfFields.SetField("InvoiceNumber", statementList.FirstOrDefault().Invoice.ToString().Trim()); pdfFields.SetField("JobNumber", statementList.FirstOrDefault().JobNumber.ToString().Trim()); pdfFields.SetField("Caller", statementList.FirstOrDefault().Caller.ToString().Trim()); pdfStamper.FormFlattening = true; // generate a flat PDF pdfStamper.Close(); pdfReader.Close(); } }
您的代码看起来很好,只缺少几个中间步骤。
由于您对每个页面使用相同的PDF模板(当需要生成两个或更多页面时),而不是使用PdfStamper
直接向Document
添加内容,因此使用PdfSmartCopy
或PdfCopy
对象。
仍然需要PdfStamper
。 但是,在这种情况下,它用于在迭代Models.Statement
集合时创建一个填充数据的内存(单个)页面。
换句话说, PdfSmartCopy/PdfCopy
维护整个语句(总页数), PdfStamper
用作缓冲区,逐页将各个语句添加到PDF中。 这是一个简单的工作示例HTTP hander(.ashx):
<%@ WebHandler Language="C#" Class="copyFillTemplate" %> using System; using System.Collections.Generic; using System.IO; using System.Web; using iTextSharp.text; using iTextSharp.text.pdf; public class copyFillTemplate : IHttpHandler { public void ProcessRequest (HttpContext context) { HttpServerUtility Server = context.Server; HttpResponse Response = context.Response; Response.ContentType = "application/pdf"; // template used to test __this__ example; // replace with __your__ PDF template string pdfTemplatePath = Server.MapPath( "~/app_data/template.pdf" ); // this example's test data; replace with __your__ data collection List statementList = Statement.GetStatements(); // COPY FROM HERE using (Document document = new Document()) { // PdfSmartCopy reduces PDF file size by reusing parts // of the PDF template, but uses more memory. you can // replace PdfSmartCopy with PdfCopy if memory is an issue using (PdfSmartCopy copy = new PdfSmartCopy( document, Response.OutputStream) ) { document.Open(); // used to test this example int counter = 0; // generate one page per statement foreach (Statement statment in statementList) { ++counter; // replace this with your PDF form template PdfReader reader = new PdfReader(pdfTemplatePath); using (var ms = new MemoryStream()) { using (PdfStamper stamper = new PdfStamper(reader, ms)) { AcroFields form = stamper.AcroFields; // replace this with your field data for each page form.SetField("title", counter.ToString()); stamper.FormFlattening = true; } reader = new PdfReader(ms.ToArray()); // add one page at a time; assumes your template is only one page. // if your template is more than one page you will need to // call GetImportedPage() for each page in your template copy.AddPage(copy.GetImportedPage(reader, 1)); } } } // COPY TO HERE } } public bool IsReusable { get { return false; } } public class Statement { public string FieldName, FieldValue; public static List GetStatements() { List s = new List (); for (int i = 0; i < 5; ++i) {s.Add(new Statement());} return s; } } }
希望内联评论有所帮助。 你显然需要删除替换我用来测试示例代码的一些部分。
虽然最后一个答案是非常好的,并帮助我解决了我的问题,但我在这里总结一下这个问题。
问题:我有一个方案可以在公司提供的模板中生成多页pdf文档。 需要生成发票声明并通过Microsoft Outlook电子邮件客户端将其附加到电子邮件中。
我使用MVC3,ASP.NET 4.0,entity framework
解:
上述就是C#学习教程:来自预定义模板的多页PDF文档分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Hosting; using System.Web.Mvc; using System.Data; using System.Data.Objects; using System.IO; using iTextSharp; using iTextSharp.text; using iTextSharp.text.html; using iTextSharp.text.pdf; using iTextSharp.text.xml; namespace InvoiceSearchTool.Controllers { public class pdfStatementController : Controller { Models.DYNAMICS_EXTEntities _db = new Models.DYNAMICS_EXTEntities(); // // GET: /pdfStatement/ public ActionResult SendPdfStatement(string InvoiceNumber) { try { InvoiceNumber = InvoiceNumber.Trim(); List statementList = new List(); //this is if you use entity framework { ObjectParameter[] parameters = new ObjectParameter[1]; parameters[0] = new ObjectParameter("InvoiceNumber", InvoiceNumber); statementList = _db.ExecuteFunction("uspInvoiceStatement", parameters).ToList(); } //others can simply use line like //statementList = GetStatementList(inviceNumber); pdfStatementController.WriteInTemplate(statementList); return RedirectToAction("Invoice", "Invoice", new { id = statementList.FirstOrDefault().Customer_ID.ToString().Trim() }); } catch (Exception e) { return View("Error"); } } public static void WriteInTemplate(List statementList) { try { string invoiceNumber = statementList.FirstOrDefault().Invoice.ToString().Trim(); using (Document document = new Document()) { FileStream fileStream = new FileStream(HostingEnvironment.MapPath("~/Content/reports/" + invoiceNumber + ".pdf"), FileMode.Create); using (PdfSmartCopy smartCopy = new PdfSmartCopy(document, fileStream)) { document.Open(); PdfReader pdfReader = new PdfReader(HostingEnvironment.MapPath("~/Content/InvoiceTemplate/invoiceTemplate.pdf")); using (var memoryStream = new MemoryStream()) { using (PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream)) { string month = null; string day = null; string year = null; AcroFields pdfFields = pdfStamper.AcroFields; {//billing address pdfFields.SetField("BillToCompany", statementList.FirstOrDefault().BillToCompany.ToString().Trim().ToUpper()); pdfFields.SetField("BillToContact", statementList.FirstOrDefault().BillToContact.ToString().Trim().ToUpper()); pdfFields.SetField("ShipToCompany", statementList.FirstOrDefault().ShipToCompany.ToString().Trim().ToUpper()); pdfFields.SetField("ShipToContact", statementList.FirstOrDefault().ShipToContact.ToString().Trim().ToUpper()); pdfFields.SetField("PONumber", statementList.FirstOrDefault().PurchaseOrderNo.ToString().Trim()); pdfFields.SetField("OrderNumber", statementList.FirstOrDefault().Order_Number.ToString().Trim()); pdfFields.SetField("ShippingMethod", statementList.FirstOrDefault().Shipping_Method.ToString().Trim()); pdfFields.SetField("PaymentTerms", statementList.FirstOrDefault().Payment_Terms.ToString().Trim()); } pdfStamper.FormFlattening = true; // generate a flat PDF } pdfReader = new PdfReader(memoryStream.ToArray()); smartCopy.AddPage(smartCopy.GetImportedPage(pdfReader, 1)); } } } emailController.CreateMessageWithAttachment(invoiceNumber); } catch (Exception e) { } } using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Outlook = Microsoft.Office.Interop.Outlook; using System.Net; using System.Net.Mail; using System.Web.Hosting; using System.Net.NetworkInformation; using System.Data.Objects; namespace InvoiceSearchTool.Controllers { public class emailController : Controller { // // GET: /email/ public static void CreateMessageWithAttachment(string invoiceNumber) { try { Outlook.Application oApp = new Outlook.Application(); Outlook.MailItem email = (Outlook.MailItem)(oApp.CreateItem(Outlook.OlItemType.olMailItem)); Models.DYNAMICS_EXTEntities _db = new Models.DYNAMICS_EXTEntities(); string recipient = null; string messageBody = null; #region set email recipients { ObjectParameter[] parameters = new ObjectParameter[1]; parameters[0] = new ObjectParameter("InvoiceNumber", invoiceNumber); List emailList = _db.ExecuteFunction("uspGetEmailAddress", parameters).ToList(); if(!string.IsNullOrEmpty(emailList[0].Email.ToString())) recipient = emailList[0].Email.ToString().Trim(); else recipient = " "; email.Recipients.Add(recipient); } #endregion //email subject email.Subject = "Invoice # " + invoiceNumber; #region set email Text { Models.EmailText emailText = _db.ExecuteFunction("uspEmailText").SingleOrDefault(); messageBody = emailText.EmailTextLine1.ToString().Trim() + "nnnnnnnnn"; messageBody += emailText.EmailTextLine2.ToString().Trim() + "n"; messageBody += emailText.EmailTextLine3.ToString().Trim(); email.Body = messageBody; } #endregion #region email attachment { string fileName = invoiceNumber.Trim(); string filePath = HostingEnvironment.MapPath("~/Content/reports/"); filePath = filePath + fileName + ".pdf"; fileName += ".pdf"; int iPosition = (int)email.Body.Length + 1; int iAttachType = (int)Outlook.OlAttachmentType.olByValue; Outlook.Attachment oAttach = email.Attachments.Add(filePath, iAttachType, iPosition, fileName); } #endregion email.Display(); //uncomment below line to SendAutomatedEmail emails atomaticallly //((Outlook.MailItem)email).Send(); } catch (Exception e) { } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1031792.html