使用iText7将PDF分割为字节数组页面:DocumentReadyListener导出问题
问题描述
在不使用文件系统的前提下,将PDF文件分割为单页对应的字节数组。参考了@AlexeySubach提供的ByteArrayPdfSplitter代码示例,但无法从DocumentReadyListener中导出分割后的字节数组内容。
原实现代码
ByteArrayPdfSplitter类
class ByteArrayPdfSplitter : PdfSplitter { private MemoryStream currentOutputStream; public ByteArrayPdfSplitter(PdfDocument pdfDocument) : base(pdfDocument) { } protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) { currentOutputStream = new MemoryStream(); return new PdfWriter(currentOutputStream); } public MemoryStream CurrentMemoryStream { get { return currentOutputStream; } } public class DocumentReadyListender : IDocumentReadyListener { private ByteArrayPdfSplitter splitter; public DocumentReadyListender(ByteArrayPdfSplitter splitter) { this.splitter = splitter; } public void DocumentReady(PdfDocument pdfDocument, PageRange pageRange) { pdfDocument.Close(); byte[] contents = splitter.CurrentMemoryStream.ToArray(); String pageNumber = pageRange.ToString(); } } }
使用示例代码
public static List<Byte[]> SplitOnPages(Byte[] bytes) { using (MemoryStream memoryStream = new MemoryStream(bytes)) { using (PdfReader reader = new PdfReader(memoryStream)) { PdfDocument docToSplit = new PdfDocument(reader); ByteArrayPdfSplitter splitter = new ByteArrayPdfSplitter(docToSplit); splitter.SplitByPageCount(1, new ByteArrayPdfSplitter.DocumentReadyListender(splitter)); } } //How do I get here the array of byte array pages?? return ... }
解决方案
核心是让DocumentReadyListener负责收集分割后的字节数组,最终在SplitOnPages方法中提取这个集合返回,具体修改如下:
修改后的ByteArrayPdfSplitter类
class ByteArrayPdfSplitter : PdfSplitter { private MemoryStream currentOutputStream; public ByteArrayPdfSplitter(PdfDocument pdfDocument) : base(pdfDocument) { } protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) { currentOutputStream = new MemoryStream(); return new PdfWriter(currentOutputStream); } public MemoryStream CurrentMemoryStream { get { return currentOutputStream; } } public class DocumentReadyListener : IDocumentReadyListener { // 新增集合存储单页字节数组 public List<byte[]> SplitPages { get; } = new List<byte[]>(); private ByteArrayPdfSplitter splitter; public DocumentReadyListener(ByteArrayPdfSplitter splitter) { this.splitter = splitter; } public void DocumentReady(PdfDocument pdfDocument, PageRange pageRange) { pdfDocument.Close(); byte[] contents = splitter.CurrentMemoryStream.ToArray(); // 将当前页的字节数组存入集合 SplitPages.Add(contents); } } }
修改后的SplitOnPages方法
public static List<byte[]> SplitOnPages(byte[] bytes) { var splitPages = new List<byte[]>(); using (MemoryStream memoryStream = new MemoryStream(bytes)) { using (PdfReader reader = new PdfReader(memoryStream)) { using (PdfDocument docToSplit = new PdfDocument(reader)) { ByteArrayPdfSplitter splitter = new ByteArrayPdfSplitter(docToSplit); var listener = new ByteArrayPdfSplitter.DocumentReadyListener(splitter); splitter.SplitByPageCount(1, listener); // 从listener中提取分割结果 splitPages.AddRange(listener.SplitPages); } } } return splitPages; }
关键说明
DocumentReadyListener的SplitPages集合为实例私有,每次分割都会创建新集合,避免多线程场景下的数据冲突。- 给
PdfDocument添加using语句,确保文档资源被正确释放。 - 分割完成后直接从listener的集合中提取结果,无需额外全局变量或复杂回调逻辑。
内容的提问来源于stack exchange,提问作者Matias Masso
相关产品推荐
相关产品推荐

