【问题标题】:iText 7.0.4.0 - Converting PdfDocument to byte arrayiText 7.0.4.0 - 将 PdfDocument 转换为字节数组
【发布时间】:2018-03-04 16:26:24
【问题描述】:

我正在尝试逐页拆分 PDF 文件,并获取每个页面文件的字节数组。但是,在 iText 7.0.4 版 C# 中,我无法将每个页面转换为字节数组。

其他解决方案中引用的方法依赖于 PdfWriter.GetInstance 或 PdfCopy,这在 iText 版本 7.0.4 中似乎不再存在。

我浏览了 iText 的示例代码和 API 文档,但无法从中提取任何有用的信息。

using (Stream stream = new MemoryStream(pdfBytes))
using (PdfReader reader = new PdfReader(stream))
using (PdfDocument pdfDocument = new PdfDocument(reader))
{
    PdfSplitter splitter = new PdfSplitter(pdfDocument);

    // My Attempt #1 - None of the document's functions seem to be of help.
    foreach (PdfDocument splitPage in splitter.SplitByPageCount(1))
    {
        // ??      
    }

    // My Attempt #2 - GetContentBytes != pdf file bytes.
    for (int i = 1; i <= pdfDocument.GetNumberOfPages(); i++)
    {
        PdfPage page = pdfDocument.GetPage(i);
        byte[] bytes = page.GetContentBytes();
    }
}

任何帮助将不胜感激。

【问题讨论】:

  • 您在处理压缩的 pdf 文件吗?压缩单个页面不会产生与压缩整个文件时相同的字节数。所以你应该找到一种比“返回文件中找到的相同字节”更好的方法来定义成功
  • 不,我正在处理未压​​缩的 PDF 文件。我所需要的只是拆分 PDF 文件并存储拆分页面以供以后使用的能力。拆分后,我无需担心将原始文档重新组合在一起。

标签: c# itext itext7


【解决方案1】:

您使用PdfSplitter 的方法是完成任务的最佳方法之一。也许开箱即用的东西不多,但PdfSplitter 是高度可定制的,如果您查看实现或只是查看 API,就会清楚哪些是注入您自己的定制行为的正确点。

您应该覆盖GetNextPdfWriter 以提供您希望在其中创建文档的任何输出媒体。您还可以使用IDocumentReadyListener 定义在另一个文档准备好后将执行的操作。

我附上了可以实现您目标的实现之一:

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();
        }
    }
}

调用基本上和你一样,但是有自定义文档就绪事件:

PdfDocument docToSplit = new PdfDocument(new PdfReader(path));
ByteArrayPdfSplitter splitter = new ByteArrayPdfSplitter(docToSplit);
splitter.SplitByPageCount(1, new ByteArrayPdfSplitter.DocumentReadyListender(splitter));

【讨论】:

  • 非常感谢!我应该更仔细地阅读文档......唯一的是 pageRange.ToString() 返回对象类型的字符串,所以我使用了 GetQualifyingPageNums,并对您的解决方案稍作修改以获得正确的页码每个页。我不会修改您的解决方案,因为这是针对我的情况的。
  • @alexey-subach,知道如何从 SplitBySize 方法中获取字节数组吗?似乎它没有 DocumentReadyListener 来通知拆分何时完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 2015-03-02
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 2019-12-10
相关资源
最近更新 更多