2017-02-01 4 views
0

У меня есть процесс, который принимает данные с HTML-страницы и помещает эти данные в PDF-файл и сохраняет PDF в сторонней системе обработки изображений.iTextSharp - Заполните PDF mulitple times и объединитесь в один pdf

HTML-страница принимает информацию для 8 пользователей. Тем не менее, в формате PDF есть только до 4 пользователей. Поэтому, если введена информация для более чем четырех, мне нужно дважды заполнить PDF и объединить эти два PDF-файла в один файл, чтобы отправить в систему обработки изображений.

Я пробовал вложенные потоки, pdfReaders, pdfStampers, но полученный PDF-файл всегда поврежден. Любая помощь будет принята с благодарностью. Заранее спасибо.

Вот код, я в настоящее время, который обрабатывает штамповки PDF, если есть 1 - 4 пользователей вошли:

var pdfTemplate = ConfigurationManager.AppSettings["PdfFileLocation"] + formName + ".pdf"; 
var pdfReader = new PdfReader(pdfTemplate); 

using (var stream = new MemoryStream()) 
{ 
    using (var pdfStamper = form == null 
    ? new PdfStamper(pdfReader, stream, '\0', false) 
    : processType == 1 // printing form 
     ? new PdfStamper(pdfReader, new FileStream(Path.GetTempPath() + "UserForm_" + UserNumber + ".pdf", FileMode.Create)) // temporarily save form 
     : new PdfStamper(pdfReader, stream, '\0', false)) // use a stream if submitting 
    { 
     var overContent1 = pdfStamper.GetOverContent(1); 
     var overContent2 = pdfStamper.GetOverContent(2); 
     var overContent3 = pdfStamper.GetOverContent(3); 
     var overContent4 = pdfStamper.GetOverContent(4); 
     var pdfFormFields = pdfStamper.AcroFields; 

     ... Code to fill out other pages of the PDF goes here ... 

     #region User Form Page #3 

     foreach (var user in users) 
     { 
      var eligibility = _sharedFormService.GetEligibility(user.Eligibility); 
      pdfFormFields.SetField("User" + nameof(user.Name) + user.Id, user.Name); 
      pdfFormFields.SetField("User" + nameof(user.Eligibility) + user.Id, eligibility); 
      pdfFormFields.SetField("User" + nameof(user.Title) + user.Id, user.Title); 
      pdfFormFields.SetField("User" + nameof(user.Type) + user.Id, user.Type); 
      pdfFormFields.SetField("User" + nameof(user.FamilyMemberName) + user.Id, user.FamilyMemberName); 

      try 
      { 
       if (user.Signature != null) 
       { 
        var sigImage = _imageHelpers.LoadImage(user.Signature); 
        var image = Image.GetInstance(sigImage, System.Drawing.Imaging.ImageFormat.Gif); 
        var sigPostitions = pdfFormFields.GetFieldPositions("User" + nameof(user.Signature) + user.Id)[0].position; 

        image.Transparency = new int[] { 255, 255 }; 
        image.SetAbsolutePosition(sigPostitions.Left, sigPostitions.Bottom); 
        image.ScalePercent(15); 

        overContent3.AddImage(image); 
       } 
      } 
      catch (DocumentException dex) 
      { 
       response.Success = false; 
       response.ErrorMessage += "StampPdf - UserSignature" + user.Id + ": " + (dex.InnerException != null 
        ? dex.InnerException.Message 
        : dex.Message) + ", "; 
      } 
      catch (IOException ioex) 
      { 
       response.Success = false; 
       response.ErrorMessage += "StampPdf - UserSignature" + user.Id + ": " + (ioex.InnerException != null 
        ? ioex.InnerException.Message 
        : ioex.Message) + ", "; 
      } 
     } 

     #endregion 

     pdfStamper.FormFlattening = true; 
    } 

    response.Stream = stream.ToArray(); 
} 

ответ

1

Через несколько дней Googling, я наконец-то нашел ответ, который я искал от IText FAQ сайта, в разделе "Объединение одинаковых форм (имеющих одинаковые поля)" (http://developers.itextpdf.com/question/how-merge-forms-different-files-one-pdf)

Вот код, который я закончил с использованием:

public static byte[] ManipulatePdf(string src, string dest) 
    { 
     var ms = new MemoryStream(); 
     Document document = new Document(); 
     PdfCopy copy = new PdfSmartCopy(document, ms); 
     copy.SetMergeFields(); 
     document.Open(); 
     List<PdfReader> readers = new List<PdfReader>(); 
     for (int i = 0; i < 2;) 
     { 
      PdfReader reader = new PdfReader(RenameFields(src, ++i)); 
      readers.Add(reader); 
      copy.AddDocument(reader); 
     } 
     document.Close(); 
     foreach (var reader in readers) 
     { 
      reader.Close(); 
     } 

     return ms.ToArray(); 
    } 

    public static byte[] RenameFields(String src, int i) 
    { 
     MemoryStream baos = new MemoryStream(); 
     PdfReader reader = new PdfReader(src); 
     PdfStamper stamper = new PdfStamper(reader, baos); 
     AcroFields form = stamper.AcroFields; 
     var keys = new HashSet<string>(form.Fields.Keys); 
     foreach (var key in keys) 
     { 
      form.RenameField(key, string.Format("{0}_{1}", key, i)); 
     } 
     stamper.Close(); 
     reader.Close(); 
     return baos.ToArray(); 
    }