Let's say I have a three page PDF and all three of them have AcroFields. I need to be able to generate a new PDF with page 2 repeated N number of times. Each new instance of page 2 will need to have the field names modified to make them distinct from the other instances of page 2. Can someone who's solved this problem before provide a syntax example?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
This is explained in the MergeForms2 example. You should split your document into 3 documents each having one page. Use the renameFields()
method to create variations of the second page.
Concatenating forms is done like this:
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();
}
A common mistake is to forget the setMergeFields()
method.
回答2:
This works but generates a large file. I guess it is because the image on page 2 is duplicated many times instead of being reused.
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();
}
}