【问题标题】:How can I replace text in PDF with iText without encoding issue? (Android)如何在没有编码问题的情况下用 iText 替换 PDF 中的文本? (安卓)
【发布时间】:2016-06-12 15:28:55
【问题描述】:

我需要一些帮助。我想在 PDF 文件中用另一个文本替换一个文本(我正在使用 iText 库),但是当我尝试使用重音字母时,它存在编码问题。

public static void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfDictionary dict = reader.getPageN(1);
    PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
    if (object instanceof PRStream) {
        PRStream stream = (PRStream) object;
        byte[] data = PdfReader.getStreamBytes(stream);


        String eredeti = "öüóá";
        final String s = new String(eredeti.getBytes(), BaseFont.CP1250);

        stream.setData(new String(data).replace("Hello World", s).getBytes());
    }
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    reader.close();
}

但是当我打开 PDF 文件时,我看到了这个: Wrong PDF

我已经尝试了所有的编码类型,以获得正确的字母 (öüóá),但它从来没有为我工作过。

有人知道我该怎么做吗?

【问题讨论】:

  • 您使用的是 unicode 字体吗?
  • 您使用getPageN() 获得的页面字典有一个/Resources 条目。此条目包含对字体的引用。如果是简单字体,则最多定义 256 个字符。很可能你需要的角色不存在。如果它是一种复合字体,它很可能只包含文档中已使用的字符子集。您需要的角色可能不存在。总而言之,这是一个糟糕的问题。不应使用您共享的代码。您尝试解决的问题记录为“不要尝试这样做”。
  • Ákos,不仅存在@Bruno 暗示的可能问题(字体中不存在字符)和明显的编码问题,而且将内容流视为字符也是非常危险的具有单一编码的字符串:除非您知道自己在做什么并相应地清理了您的输入,否则您很有可能使流内容无效。 PDFBox 曾经有一个捆绑示例做类似的事情,由于上述所有原因,他们将其从分发中删除,现在也警告不要做类似的事情。
  • 谢谢大家的快速支持...如果我的代码这样错了,有什么方法可以做我想做的事,还是应该放弃?
  • 有什么方法可以做我想做的事,还是我应该放弃 - 这取决于你有多少时间,以及你是否只想改变一个很少有内部简单构建的 PDF 或来自野外的通用 PDF。由于涉及不同的编码和子集以及可能需要对文本进行重排,编辑 PDF 内容很困难。另一方面,如果您知道您的 PDF 在这些方面很简单(即仅使用标准编码、字体(如果嵌入)相当完整,不需要重排),那么有一些方法可以用大量的时间和资源来做到这一点。

标签: android pdf encoding replace itext


【解决方案1】:

我已经找到了解决方案;)

问题是,我在将字符串放入 PDF 文件之前已对其进行了编码。您应该在将字符串准确放入 PDF 时对其进行编码,就像这里一样:

    stream.setData(new String(data).replace("Hello World", s).getBytes("ISO-8859-2"));

你可以在这里看到我的代码的最终形式:

public static void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfDictionary dict = reader.getPageN(1);
    PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
    if (object instanceof PRStream) {
        PRStream stream = (PRStream) object;
        byte[] data = PdfReader.getStreamBytes(stream);


        String eredeti = "öűóá";
        final String s = new String(eredeti.getBytes());

        stream.setData(new String(data).replace("Hello World", s).getBytes("ISO-8859-2"));
    }
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();

    Paragraph preface = new Paragraph();
    preface.setAlignment(Element.ALIGN_CENTER);

    reader.close();
}

【讨论】:

  • 有一些 pdf 可以使用。还有更多这不起作用。
  • 我测试了几个 pdf 文件,但每次都对我有用:/
  • 以例如free copy of the PDF specification,第 1 页,标题页,并尝试将“First”(来自“First Edition”)替换为“Second”;或“管理”(来自“文档管理”)通过“显示”;或“2008”(来自“2008-7-1”)由“1234”。而且这份文件内部非常平淡……
  • @mkl,当 PdfObject object = dict.getDirectObject(PdfName.CONTENTS); 返回 PRStream 的对象时,这可以正常工作
  • @DanyalSandeelo 这是必要的先决条件,但不是充分条件。
猜你喜欢
  • 2020-02-21
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多