首页 > 解决方案 > 无法将“iTextSharp.text.pdf.PdfArray”类型的对象转换为“iTextSharp.text.pdf.PRStream”类型

问题描述

我必须将数字“14-1”替换为“10-2”。我正在使用以下 iText 代码,但收到以下类型转换错误。任何人都可以通过修改程序并消除铸造问题来帮助我:

我有很多 PDF,我必须在同一位置替换数字。我还需要从逻辑上理解如何做到这一点:

using System;
using System.IO;
using System.Text;
using iTextSharp.text.io;
using iTextSharp.text.pdf;

using System.Windows.Forms;

namespace iText5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public const string src = @"D:\test1\A.pdf";
        public const string dest = @"D:\test1\ENV1.pdf";

        private void button1_Click(object sender, EventArgs e)
        {
            FileInfo file = new FileInfo(dest);
            file.Directory.Create();
            manipulatePdf(src, dest);
        }

        public void manipulatePdf(String src, String dest)
        {

        PdfReader reader = new PdfReader(src);
        PdfDictionary dict = reader.GetPageN(1);

        PdfObject obj = dict.GetDirectObject(PdfName.CONTENTS);

        PRStream stream = (PRStream)obj;

        byte[] data = PdfReader.GetStreamBytes(stream);
        string xyz = Encoding.UTF8.GetString(data);

        byte[] newBytes = Encoding.UTF8.GetBytes(xyz.Replace("14-1", "10-2"));
        stream.SetData(newBytes);

        PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
        stamper.Close();
        reader.Close();

        }

    }
}

标签: c#itext

解决方案


这是个问题:

PdfDictionary dict = reader.GetPageN(1);
PdfObject obj = dict.GetDirectObject(PdfName.CONTENTS);
PRStream stream = (PRStream)obj;

首先你得到一个页面字典。该页面字典有一个/Contents条目。如果您阅读 PDF 标准 (ISO 32000),那么您会看到/Contents条目的值可以数组。你假设它总是一个流。在某些情况下,您的代码可以工作,但在/Contents条目的值是对一系列流的引用数组的情况下,您将收到类转换错误(由于流数组不同的明显原因作为流)。

我认为你想做这样的事情:

byte[] data = reader.GetPageContent(i);
string xyz = PdfEncodings.ConvertToString(data, PdfObject.TEXT_PDFDOCENCODING);
string abc = xyz.Replace("14-1", "10-2");                 
reader.SetPageContent(i, PdfEncodings.ConvertToBytes(abc, PdfObject.TEXT_PDFDOCENCODING));

但是,这是一个非常糟糕的主意,因为这些问题的答案中解释了原因:

您假设您会在内容中找到string具有值的文字"14-1"。这对于简单的 PDF 文档可能是正确的,但在许多情况下,"14-1"页面上的外观(您可以用眼睛阅读)并不意味着该字符串"14-1"在内容中存在(您使用 提取GetPageContent)。该字符串可以是 XObject 的一部分,或者可以以不会以任何方式改变"14-1"的方式构造要呈现的语法。xyz.Replace("14-1", "10-2")xyz

底线:PDF 不是一种编辑格式。PDF 文件中的页面包含在绝对位置添加的内容。如果您更改页面上的内容,它不会重排(例如,如果您添加额外的内容,现有内容将不会移动到下一行或下一页)。您应该编辑用于创建文档的源,而不是编辑 PDF 文档,然后从该源创建新的 PDF。

重要提示:您使用的是旧版本的 iText。两年多前,我们放弃了iTextSharp这个名称,转而使用iText for .NET。当前版本的 iText 是 iText 7.1.2;见 Nuget:https ://www.nuget.org/packages/itext7/

很多人认为 iText 5.5.13 是最新版本。这种假设是错误的。iText 5 已停产,不再受支持。最近的 5.5.x 版本是针对无法立即迁移到 iText 7 的付费客户的维护版本。


推荐阅读