c# - 无法将“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();
}
}
}
解决方案
这是个问题:
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));
但是,这是一个非常糟糕的主意,因为这些问题的答案中解释了原因:
- 使用 itextSharp 替换 pdf 文档中的文本
- PDF文本替换不起作用
- C# 或 .net 中是否有任何 API 可以编辑 pdf 文档?
- 使用 ContentByteUtils 进行原始 PDF 操作
- ...
您假设您会在内容中找到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 的付费客户的维护版本。
推荐阅读
- docker - Dockerhub 显示几秒钟前提取的图像
- python - 在 3 个数据帧之间映射值
- random - 有效地对至少 k 个长度为 l 的随机 0-1 序列进行采样
- sql - sybase对表中的所有记录执行更新数学运算时如何处理空列?
- ios - 使用 REST API ObjC 使用 GameCenter 登录 Firebase
- material-ui - 是的验证,不显示表单字段的错误消息
- android-jetpack-compose - 如何在 jetpack compose 中插入矢量动画或矢量 gif 图像?
- docker - kubernetes 是否支持使用本地 GPU 机器设置集群
- flutter - 使用相机颤振拍照
- javascript - 如何在电子应用程序包时安装node_modules?