2017-07-27 91 views
0

我正在编写一个程序来填写有36个订单项的PDF订单。有时会有超过36个项目,因此我希望能够在保存之前为剩余项目添加第二个页面。这里是我目前有填充PDF行项目代码:如何使用iTextSharp的PdfReader和Stamper制作多个页面?

private SaveResult WritePDF(ref ObservableCollection<OrderLineItem> saveObj) 
{ 
    try 
    { 
     if (saveObj == null) throw new ArgumentNullException("Save Object is null"); 
     var theForm = ReadResource("LineItemOrderForm"); 
     var sfd = new SaveFileDialog 
     { 
      AddExtension = true, 
      InitialDirectory = DesktopPath, 
      DefaultExt = ".pdf", 
      RestoreDirectory = true, 
      Filter = "Adobe PDF Files (.pdf)|*.pdf", 
     }; 
     var saveResult = sfd.ShowDialog(); 
     if (saveResult == false) return SaveResult.Cancelled; 
     var outPath = sfd.FileName; 

     var timesBasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "TIMESBD.TTF"); 
     var timesBaseFont = BaseFont.CreateFont(timesBasePath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); 

     using (var pdfReader = new PdfReader(theForm)) 
     { 
      var fs = new FileStream(outPath, FileMode.Create); 

      using (var pdfStamper = new PdfStamper(pdfReader, fs)) 
      { 
       var form = pdfStamper.AcroFields; 
       form.AddSubstitutionFont(timesBaseFont); 

       var i = 1; 
       form.SetField("OrderFormDealerName", Constants.DealerName); 
       form.SetFieldProperty("OrderFormDealerName", "textcolor", BaseColor.BLACK, null); 
       foreach (var item in saveObj) 
       { 
        form.SetField($"LineItem{i:D2}", item.LineItemNumber.ToString(CultureInfo.InvariantCulture)); 
        form.SetFieldProperty($"LineItem{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"Qty{i:D2}", item.Quantity.ToString(CultureInfo.InvariantCulture)); 
        form.SetFieldProperty($"Qty{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"PartNumber{i:D2}", item.PartNumber); 
        form.SetFieldProperty($"PartNumber{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"Hinging{i:D2}", item.Hinging.ToString()); 
        form.SetFieldProperty($"Hinging{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"Finished{i:D2}", item.Finished.ToString()); 
        form.SetFieldProperty($"Finished{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"UnitPrice{i:D2}", $"{item.UnitPrice:C0}"); 
        form.SetFieldProperty($"UnitPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"ModPrice{i:D2}", $"{item.ModifyPrice:C0}"); 
        form.SetFieldProperty($"ModPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

        form.SetField($"ExtPrice{i:D2}", $"{item.ExtendedPrice:C0}"); 
        form.SetFieldProperty($"ExtPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

        i++; 
       } 
       pdfStamper.FormFlattening = false; 
       pdfStamper.Close(); 
      } 
      pdfReader.Close(); 
      return SaveResult.Success; 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message, "WritePDF()"); 
     return SaveResult.Failure; 
    } 
} 

什么是适应这个代码来实现我期待的结果的最佳方式?

编辑:我正在使用通过NuGet包管理器安装的iTextSharp版本5.5.11。

回答

0

我最终决定最简单的方法是制作临时PDF文件,合并它们,保存合并的文件,然后删除临时文件。

这里是我张贴在原来的问题的方法中,改性:

private SaveResult WritePDF(ref List<OrderLineItem> saveObj) 
{ 
    try 
    { 
     if (saveObj == null) throw new ArgumentNullException("Save Object is null"); 
     var theForm = ReadResource("LineItemOrderForm"); 
     var pageCount = 1.0; 
     var multiPage = (saveObj.Count > 36); 
     var multiList = new List<List<OrderLineItem>>(); 
     var fileList = new List<string>(); 
     if (multiPage) 
     { 
      var temp = (saveObj.Count/36.0); 
      pageCount = Math.Ceiling(temp); 
      multiList = saveObj.ChunkBy(36); 
     } 
     else 
     { 
      multiList.Add(saveObj); 
     } 
     var sfd = new SaveFileDialog 
     { 
      AddExtension = true, 
      InitialDirectory = DesktopPath, 
      DefaultExt = ".pdf", 
      RestoreDirectory = true, 
      FileName = "Pioneer Order Form", 
      Filter = "Adobe PDF Files (.pdf)|*.pdf", 
     }; 
     var saveResult = sfd.ShowDialog(); 
     if (saveResult == false) return SaveResult.Cancelled; 
     var fileName = sfd.FileName; 

     var timesBasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "TIMESBD.TTF"); 
     var timesBaseFont = BaseFont.CreateFont(timesBasePath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); 
     var pageNumber = 1; 

     foreach (var page in multiList) 
     { 
      var tempFileName = Path.Combine(BasePath, Extensions.TempPdfName()); 
      fileList.Add(tempFileName); 

      using (var pdfReader = new PdfReader(theForm)) 
      { 
       var fs = new FileStream(tempFileName, FileMode.Create); 

       using (var pdfStamper = new PdfStamper(pdfReader, fs)) 
       { 
        var form = pdfStamper.AcroFields; 
        form.AddSubstitutionFont(timesBaseFont); 

        var i = 1; 
        form.SetField("OrderFormDealerName", Constants.DealerName); 
        form.SetFieldProperty("OrderFormDealerName", "textcolor", BaseColor.BLACK, null); 

        form.SetField("PageNumber", pageNumber); 
        form.SetField("TotalPages", Convert.ToInt32(pageCount)); 

        foreach (var item in page) 
        { 
         form.SetField($"LineItem{i:D2}", item.LineItemNumber); 
         form.SetFieldProperty($"LineItem{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"Qty{i:D2}", item.Quantity); 
         form.SetFieldProperty($"Qty{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"PartNumber{i:D2}", item.PartNumber); 
         form.SetFieldProperty($"PartNumber{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"Hinging{i:D2}", item.Hinging); 
         form.SetFieldProperty($"Hinging{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"Finished{i:D2}", item.Finished); 
         form.SetFieldProperty($"Finished{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"UnitPrice{i:D2}", $"{item.UnitPrice:C0}"); 
         form.SetFieldProperty($"UnitPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"ModPrice{i:D2}", $"{item.ModifyPrice:C0}"); 
         form.SetFieldProperty($"ModPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

         form.SetField($"ExtPrice{i:D2}", $"{item.ExtendedPrice:C0}"); 
         form.SetFieldProperty($"ExtPrice{i:D2}", "textcolor", BaseColor.BLACK, null); 

         i++; 
        } 
        pdfStamper.FormFlattening = true; 

        pdfStamper.Close(); 
       } 
       pdfReader.Close(); 
      } 
      pageNumber++; 
     } 

     var result = MergePDFs(fileList, fileName); 
     foreach (var file in fileList) 
     { 
      File.Delete(file); 
     } 
     return result ? SaveResult.Success : SaveResult.Failure; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message, "WritePdf()"); 
     return SaveResult.Failure; 
    } 
} 

我利用从another question's answer溶液合并临时PDF文件:

public static bool MergePDFs(IEnumerable<string> fileNames, string targetPdf) 
{ 
    var merged = true; 
    using (var stream = new FileStream(targetPdf, FileMode.Create)) 
    { 
     var document = new Document(); 
     var pdf = new PdfCopy(document, stream); 
     PdfReader reader = null; 
     try 
     { 
      document.Open(); 
      foreach (var file in fileNames) 
      { 
       reader = new PdfReader(file); 
       pdf.AddDocument(reader); 
       reader.Close(); 
      } 
     } 
     catch (Exception) 
     { 
      merged = false; 
      reader?.Close(); 
     } 
     finally 
     { 
      document.Close(); 
     } 
    } 
    return merged; 
} 

我也使用的.ChunkBy(int)扩展from here将源列表拆分为N个36个订单项列表:

public static List<List<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize) 
{ 
    return source 
     .Select((x, i) => new { Index = i, Value = x }) 
     .GroupBy(x => x.Index/chunkSize) 
     .Select(x => x.Select(v => v.Value).ToList()) 
     .ToList(); 
} 
相关问题