2011-12-15 30 views
4

我需要使用一些預定義的公司模板以PDF生成發票報告。我能夠創建/生成使用iTextSharp的PDF報告單頁來自預定義模板的多頁PDF文檔

問題:發票聲明跨越多頁時出現問題。我無法將報告(發票聲明)擴展到下一頁(第2頁)。如果所有數據都不能放在一個頁面上,它應該寫在第二頁上,同時仍然使用公司模板。

模板存在於以下路徑:

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<Models.Statement> statementList = new List<Models.Statement>(); 
       statementList = _db.ExecuteFunction<Models.Statement>("uspInvoiceStatement", parameters).ToList<Models.Statement>(); 
       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<Models.Statement> 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(); 
    } 
} 
+0

你重新使用** **相同​​模板的每一頁,或者使用不同的** * *第二頁的模板? – kuujinbo 2011-12-15 08:59:30

+0

我爲每個頁面使用相同的模板。 – 14578446 2011-12-15 13:38:01

回答

6

您的代碼看起來不錯,只缺少幾個中間步驟。

由於您使用相同的PDF模板爲每個頁面(當兩個或更多的頁面需要生成),而不是使用PdfStamper直接添加內容到Document,您使用PdfSmartCopyPdfCopy對象。

PdfStamper仍然需要。但是,在這種情況下,它會用於創建一個充滿數據的內存(單頁)頁面,就像您在遍歷Models.Statement集合時一樣。

換句話說,​​3210作爲一個整體來維護您的語句,(總頁數)和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<Statement> 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<Statement> GetStatements() { 
     List<Statement> s = new List<Statement>(); 
     for (int i = 0; i < 5; ++i) {s.Add(new Statement());} 
     return s; 
    } 
    } 
} 

希望內聯評論幫助。你顯然需要刪除我用來測試示例代碼的部分代碼。

0

雖然最後一個答案是一個非常好的答案,並幫助我解決了我的問題,但我在這裏總結了這個問題。

問題:我在公司提供的模板中生成了多頁pdf文檔。需要生成發票聲明並通過Microsoft Outlook電子郵件客戶端將它們附加到電子郵件。

我用MVC3,ASP.NET 4.0中,實體框架

解決方案:

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<Models.Statement> statementList = new List<Models.Statement>(); 
      //this is if you use entity framework 
      { 
       ObjectParameter[] parameters = new ObjectParameter[1]; 
      parameters[0] = new ObjectParameter("InvoiceNumber", InvoiceNumber); 

       statementList = _db.ExecuteFunction<Models.Statement>("uspInvoiceStatement", parameters).ToList<Models.Statement>(); 
      } 

      //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<Models.Statement> 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<Models.EmailAddress> emailList = _db.ExecuteFunction<Models.EmailAddress>("uspGetEmailAddress", parameters).ToList<Models.EmailAddress>(); 
       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<Models.EmailText>("uspEmailText").SingleOrDefault(); 

       messageBody = emailText.EmailTextLine1.ToString().Trim() + "\n\n\n\n\n\n\n\n\n"; 
       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) 
     { 

     } 

    }