这里的问题是PdfSplitter 方法返回的文档,特别是ExtractPageRange,是iText 7 文档写入,即这些PdfDocument 实例已被实例化为PdfWriter.
此类文档受到某些限制,特别是不能从中复制页面。有关这方面的详细信息,请阅读答案 here 和 here。
要使这些结果文档(以及带有它们的整个PdfSplitter 类)具有任何价值,因此,您需要一种方法来定义这些文档的PdfWriter 对象写入的位置。还有一种方法,虽然不是很直观的方法:你必须覆盖 PdfSplitter 的 GetNextPdfWriter 方法,它最初看起来像这样:
/// <summary>This method is called when another split document is to be created.</summary>
/// <remarks>
/// This method is called when another split document is to be created.
/// You can override this method and return your own
/// <see cref="iText.Kernel.Pdf.PdfWriter"/>
/// depending on your needs.
/// </remarks>
/// <param name="documentPageRange">the page range of the original document to be included in the document being created now.
/// </param>
/// <returns>the PdfWriter instance for the document which is being created.</returns>
protected internal virtual PdfWriter GetNextPdfWriter(PageRange documentPageRange) {
return new PdfWriter(new ByteArrayOutputStream());
}
在像您这样的用例中,您只希望最终要写入文件的单个返回文档,您可以这样做:
class MySplitter : PdfSplitter
{
public MySplitter(PdfDocument pdfDocument) : base(pdfDocument)
{
}
protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange)
{
String toFile = @"C:\Users\Standard\Downloads\Result\Extracted.pdf";
return new PdfWriter(toFile);
}
}
随着PdfWriter 实例化移动到自定义拆分器中,您的主代码将减少到
string file = @"C:\Users\Standard\Downloads\Merged\CK 2002989 $29,514.42 02.12.20.pdf";
string range = "1, 4, 8";
var pdfDocumentInvoiceNumber = new PdfDocument(new PdfReader(file));
var split = new MySplitter(pdfDocumentInvoiceNumber);
var result = split.ExtractPageRange(new PageRange(range));
result.Close();
在像您这样的用例中,这确实看起来很奇怪,必须从 PdfSplitter 派生一个自定义类,只是为了从源 PDF 中提取几页到结果 PDF。 ExtractPageRange 的附加 PdfWriter 参数不会让它变得更容易吗?
但请注意,PdfSplitter 类的主要目标是使用 ExtractPageRanges 和 SplitBy... 方法将文档分成许多部分,在这种情况下,您需要提供更大的,可能不确切知道PdfWriters 的数量...一点也不容易!
当然,更好的解决方案可能是注入一些 lambda 表达式或一些其他回调机制。例如:
class ImprovedSplitter : PdfSplitter
{
private Func<PageRange, PdfWriter> nextWriter;
public ImprovedSplitter(PdfDocument pdfDocument, Func<PageRange, PdfWriter> nextWriter) : base(pdfDocument)
{
this.nextWriter = nextWriter;
}
protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange)
{
return nextWriter.Invoke(documentPageRange);
}
}
你可以这样使用
string file = @"C:\Users\Standard\Downloads\Merged\CK 2002989 $29,514.42 02.12.20.pdf";
string range = "1, 4, 8";
var pdfDocumentInvoiceNumber = new PdfDocument(new PdfReader(file));
var split = new ImprovedSplitter(pdfDocumentInvoiceNumber, pageRange => new PdfWriter(@"C:\Users\Standard\Downloads\Result\Extracted.pdf"));
var result = split.ExtractPageRange(new PageRange(range));
result.Close();