2014-05-18 1 views
0

3 페이지짜리 PDF가 있고 그 중 3 페이지에 모두 AcroFields가 있다고 가정 해 보겠습니다. 페이지 2를 N 번 반복하여 새 PDF를 생성 할 수 있어야합니다. 페이지 2의 각각의 새로운 인스턴스는 필드 이름을 페이지 2의 다른 인스턴스와 구분되도록 수정해야합니다.이 문제를 해결 한 사람이 구문 예제를 제공 할 수 있습니까?iTextSharp 기존 페이지의 새 인스턴스 추가

답변

0

이 방법은 작동하지만 큰 파일을 생성합니다. 나는 2 페이지의 이미지가 재사용되는 대신 여러 번 복제되기 때문이라고 생각합니다.

public static void ExpandRepeatingPages(string sourcePdfPath, string outputPdfPath) 
{ 
    /* figure out how many pages we are working with */ 
    var transientPdfReader = new PdfReader(sourcePdfPath); 
    var numberOfPages = transientPdfReader.NumberOfPages; 
    transientPdfReader.Close(); 

    var outputFileStream = new FileStream(outputPdfPath, FileMode.Create); 
    var pdfCopyFields = new PdfCopyFields(outputFileStream); 

    foreach (var pageNumber in Enumerable.Range(1, numberOfPages)) 
    { 
     var pdfBytes = ExtractPageToBytes(sourcePdfPath, pageNumber); 
     var pdfReader = new PdfReader(pdfBytes); 
     pdfCopyFields.AddDocument(pdfReader); 
     pdfReader.Close(); 

     if (pageNumber == 2) 
     { 
      foreach (var extraPageNumber in Enumerable.Range(2, 200)) 
      { 
       var extraPagePdfBytes = RenamePageFields(pdfBytes, extraPageNumber); 
       pdfReader = new PdfReader(extraPagePdfBytes); 
       pdfCopyFields.AddDocument(pdfReader); 
       pdfReader.Close(); 
      } 
     } 
    } 

    pdfCopyFields.Close(); 
} 

public static byte[] ExtractPageToBytes(string sourcePdfPath, int pageNumber) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     var pageNumbers = new System.Collections.ArrayList { pageNumber }; 
     var pdfReader = new PdfReader(sourcePdfPath); 
     var pdfCopyFields = new PdfCopyFields(memoryStream); 

     pdfReader.SelectPages(pageNumbers); 
     pdfCopyFields.AddDocument(pdfReader); 
     pdfReader.RemoveUnusedObjects(); 
     pdfCopyFields.Close(); 
     pdfReader.Close(); 
     return memoryStream.ToArray(); 
    } 
} 

private static byte[] RenamePageFields(byte[] pdfBytes, int pageNumber) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     var pdfReader = new PdfReader(pdfBytes); 
     var pdfStamper = new PdfStamper(pdfReader, memoryStream); 
     var acroFields = pdfStamper.AcroFields; 
     var fieldNames = acroFields.Fields.Keys.Cast<String>().ToList(); 

     foreach (var fieldName in fieldNames) 
     { 
      var newName = String.Format("{0}_{1}", fieldName, pageNumber); 
      acroFields.RenameField(fieldName, newName); 
     } 

     pdfStamper.Close(); 
     pdfReader.Close(); 
     return memoryStream.ToArray(); 
    } 
} 
1

이 내용은 MergeForms2 예제에서 설명합니다. 문서를 하나의 페이지가있는 3 개의 문서로 분할해야합니다. renameFields() 메서드를 사용하여 두 번째 페이지의 변형을 만듭니다.

여러개 쓰기 형태는 다음과 같이 수행됩니다

Document document = new Document(); 
PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest)); 
copy.setMergeFields(); 
document.open(); 
List<PdfReader> readers = new ArrayList<PdfReader>(); 
for (int i = 0; i < 3;) { 
    PdfReader reader = new PdfReader(renameFields(src, ++i)); 
    readers.add(reader); 
    copy.addDocument(reader); 
} 
document.close(); 
for (PdfReader reader : readers) { 
    reader.close(); 
} 

일반적인 실수는 setMergeFields() 방법을 잊지하는 것입니다.

+0

여기 주름은 iTextSharp 4.1.6.0을 AGPL 버전의 라이센스 제한 때문에 사용해야한다는 것입니다. 나는 누군가가 그 버전을 더 이상 사용하지 않는다고 확신하기 때문에 아무도 그 경고를 포함시키지 않고 답장을하지 않으려 고하지 않았다. 이전 버전에는 catch-22가 포함되어있는 것으로 보입니다. 나는 PdfSmartCopy를 거의 필요로하는 2 페이지의 200 인스턴스를 가질 수 있습니다. 그러나 필자가 acro-fields를 다루고 있기 때문에 문서는 PdfCopyFields를 사용해야한다고 믿습니다. – tponthieux

+0

"AGPL의 라이센스 제한으로 인해"경제에 대한 재능이 부족합니다. 오래된 소프트웨어를 사용하는 데 드는 비용은 상업용 라이센스 비용보다 높습니다. –

+0

비용은 실제로 문제가 아닙니다. 시간이 없으면 내부 구매 절차가 오래 걸립니다. 내일 솔루션을 제공해야합니다. 현재 버전은 PdfCopyFields 대 PdfSmartCopy 잡아 - 22 주위에 어떤 새로운 기능을 가지고 있습니까? – tponthieux

관련 문제