【问题标题】:Does PDF file contain iref stream?PDF 文件是否包含 iref 流?
【发布时间】:2012-09-28 17:41:52
【问题描述】:

我仍在努力从 PDF 文件中读取数据。
我使用 PDFsharp,如何在不使用 Open 方法的情况下检查文件是否包含 iref 流。如果文件包含 iref 流,方法 Open 会抛出异常。

【问题讨论】:

  • 我不知道 PDF#,但我的解决方案是打开 PDF 并获取特定的异常
  • pdfsharp 的新版本可用它仍然是测试版:1.50.4000-beta3b,但它解决了问题。您可以从 nuget nuget.org/packages/PdfSharp/1.50.4000-beta3b 下载它

标签: c# pdf pdfsharp


【解决方案1】:

有一个已知的解决方法允许您打开包含 iref 的 pdf 文件:您可以找到 here 的完整线程。

简单总结一下解决方法:

  1. 下载并包含iTextSharp 4.1.6 library
  2. 将代码文件中的以下代码粘贴到您的项目中:

-

using System;
using System.IO;

namespace PdfSharp.Pdf.IO
{
    static public class CompatiblePdfReader
    {
        /// <summary>
        /// uses itextsharp 4.1.6 to convert any pdf to 1.4 compatible pdf, called instead of PdfReader.open
        /// </summary>
        static public PdfDocument Open(string pdfPath)
        {
            using (var fileStream = new FileStream(pdfPath, FileMode.Open, FileAccess.Read))
            {
                var len = (int)fileStream.Length;
                var fileArray = new Byte[len];
                fileStream.Read(fileArray, 0, len);
                fileStream.Close();

                return Open(fileArray);
            }
        }

        /// <summary>
        /// uses itextsharp 4.1.6 to convert any pdf to 1.4 compatible pdf, called instead of PdfReader.open
        /// </summary>
        static public PdfDocument Open(byte[] fileArray)
        {
            return Open(new MemoryStream(fileArray));
        }

        /// <summary>
        /// uses itextsharp 4.1.6 to convert any pdf to 1.4 compatible pdf, called instead of PdfReader.open
        /// </summary>
        static public PdfDocument Open(MemoryStream sourceStream)
        {
            PdfDocument outDoc;
            sourceStream.Position = 0;

            try
            {
                outDoc = PdfReader.Open(sourceStream, PdfDocumentOpenMode.Import);
            }
            catch (PdfReaderException)
            {
                //workaround if pdfsharp doesn't support this pdf
                sourceStream.Position = 0;
                var outputStream = new MemoryStream();
                var reader = new iTextSharp.text.pdf.PdfReader(sourceStream);
                var pdfStamper = new iTextSharp.text.pdf.PdfStamper(reader, outputStream) {FormFlattening = true};
                pdfStamper.Writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_4);
                pdfStamper.Writer.CloseStream = false;
                pdfStamper.Close();

                outDoc = PdfReader.Open(outputStream, PdfDocumentOpenMode.Import);
            }

            return outDoc;
        }
    }
}
  1. 将所有对 PdfReader.Open 的呼叫更改为 CompatiblePdfReader.Open

它对我来说就像一个魅力,希望这对你有帮助。

【讨论】:

  • 直到出现异常:PdfReader 未使用所有者密码打开。我还没有克服这一点。我认为您可以使用较旧(4.0.4 之前)版本的 iTextSharp。
  • 希望我能多次投票!知道怎么做就这么简单!!
  • 这是一个救生员!我需要将生成的 PDF 与一些我无法控制的提供的 PDF 合并。这个解决方案让我可以同时使用它们,并且能够在不丢弃不兼容的情况下合并它们。
  • 答案看起来不错 - 但值得注意的是,iTextSharp 使用 AGPL,因此对于大多数商业运营,需要支付许可费。
  • @StuartMoore 链接版本在 MPL / LGPLv2 下
【解决方案2】:

PDFsharp 1.32 及更早版本不支持 iref 流。

自 2015 年 12 月以来,我们推出了支持 iref 流的 PDFsharp 1.50。

【讨论】:

  • 撰写本文时,您需要从 NuGet 中选择预发布版本...
  • 谢谢这是完美的
  • 1.50.3638-beta 有其他问题,PdfReader.Open() 挂起。它不是固定的,仍然存在于版本 1.50.4000-beta3b 中,这是当前的最后一个版本。请参阅Bug: PdfReader.Open() (PDFsharp 1.5) 线程。
【解决方案3】:

虽然回复晚了,但可能有用。

我处于同样的情况(使用 pdfSharp 的 C# 项目)。我有一个 PowerShell 脚本,它在合并时忽略带有 iref 流的文件(因此不会引发异常)。

Function Merge-PDF {
    Param($path, $filename)                        



    $output = New-Object PdfSharp.Pdf.PdfDocument
    $PdfReader = [PdfSharp.Pdf.IO.PdfReader]
    $PdfDocumentOpenMode = [PdfSharp.Pdf.IO.PdfDocumentOpenMode]                        

    foreach($i in (gci $path *.pdf -Recurse)) {
        $input = New-Object PdfSharp.Pdf.PdfDocument
        $input = $PdfReader::Open($i.fullname, $PdfDocumentOpenMode::Import)
        $input.Pages | %{$output.AddPage($_)}
    }                        

    $output.Save($filename)
}

Merge-PDF -path c:\reports -filename c:\reports\zzFull_deck.pdf

稍后肯定会发布与上述函数等效的 C#。

【讨论】:

  • 他再也没有回来。
  • 用空的 catch 块处理 PdfSharp.Pdf.IO.PdfReaderException 就可以了。
【解决方案4】:

解决方法是捕获PdfSharp.Pdf.IO.PdfReaderException,并忽略导致此类异常的文件。

PdfDocument inputPDFDocument = new PdfDocument();
try
{
    inputPDFDocument = PdfReader.Open(pdfFile, PdfDocumentOpenMode.Import);
}
catch (PdfSharp.Pdf.IO.PdfReaderException)
{
    //
}

【讨论】:

  • 忽略它们?就像忽略我的一些工作要求一样?是的,听起来像是一个修复
  • @mxmissile 确实如此。查看 Vive la deraison 对 PDFsharp 较新版本中的解决方案的回答。
猜你喜欢
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 2019-11-27
  • 2019-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多