Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java apachepdfbox:编码问题_Java_Pdfbox - Fatal编程技术网

Java apachepdfbox:编码问题

Java apachepdfbox:编码问题,java,pdfbox,Java,Pdfbox,我有一个PDF模板&试图替换其中的一些单词。我使用以下代码: private PDDocument replaceText(PDDocument document, String searchString, String replacement) throws IOException { if (searchString.isEmpty() || replacement.isEmpty()) { return document; } PDPageTree

我有一个PDF模板&试图替换其中的一些单词。我使用以下代码:

private PDDocument replaceText(PDDocument document, String searchString, String replacement) throws IOException {
    if (searchString.isEmpty() || replacement.isEmpty()) {
        return document;
    }
    PDPageTree pages = document.getDocumentCatalog().getPages();
    for (PDPage page : pages) {
        PDFStreamParser parser = new PDFStreamParser(page);
        parser.parse();
        List<Object> tokens = parser.getTokens();
        for (int j = 0; j < tokens.size(); j++) {
            Object next = tokens.get(j);
            if (next instanceof Operator) {
                Operator op = (Operator) next;
                //Tj and TJ are the two operators that display strings in a PDF
                if (op.getName().equals("Tj")) {
                    // Tj takes one operator and that is the string to display so lets update that operator
                    COSString previous = (COSString) tokens.get(j - 1);
                    String string = previous.getString();
                    if (searchString.equals(string)) {
                        System.out.println(string);
                    }
                    string = string.replaceFirst(searchString, replacement);
                    previous.setValue(string.getBytes());
                } else if (op.getName().equals("TJ")) {
                    COSArray previous = (COSArray) tokens.get(j - 1);
                    for (int k = 0; k < previous.size(); k++) {
                        Object arrElement = previous.getObject(k);
                        if (arrElement instanceof COSString) {
                            COSString cosString = (COSString) arrElement;
                            String string = cosString.getString();
                            if (searchString.equals(string)) {
                                System.out.println(string);
                            }
                            string = StringUtils.replaceOnce(string, searchString, replacement);
                            cosString.setValue(string.getBytes());
                        }
                    }
                }
            }
        }
        // now that the tokens are updated we will replace the page content stream.
        PDStream updatedStream = new PDStream(document);
        OutputStream out = updatedStream.createOutputStream();
        ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
        tokenWriter.writeTokens(tokens);
        page.setContents(updatedStream);
        out.close();
    }
    return document;
}
private PDDocument replaceText(PDDocument文档、字符串搜索字符串、字符串替换)引发IOException{
if(searchString.isEmpty()| | replacement.isEmpty()){
归还文件;
}
PDPageTree pages=document.getDocumentCatalog().getPages();
用于(第页:页){
PDFStreamParser=新的PDFStreamParser(第页);
parser.parse();
List tokens=parser.getTokens();
对于(int j=0;j
我的PDF模板只有3个字符串:file:///C/Users/Mi/Downloads/converted.txt“,”[10.03.2020 18:43:57]“和“你好!!!”。 前两个字符串搜索正确,但第三个看起来像“KHOOR…”:

据我所知,存在编码不匹配。当我试图替换“file:///C/Users/Mi/Downloads/converted.txt用“Hello!”替换为“ello”,不显示大写字母和标记。据我所知,主要区别在于字体。“你好”有字体设置,其他人没有

源PDF在这里:

请给出建议,如何从PDF中获取文本作为正确的字符串并替换它。

这个答案实际上是一个解释,为什么一个通用的任务解决方案即使不是不可能的,至少也是非常复杂的。在良好的情况下,即对于受特定限制的PDF,可以成功地使用类似于您的代码,但您的示例PDF表明,您显然想要操纵的PDF并没有受到这样的限制

为什么自动替换文本很困难/不可能 有许多因素阻碍了PDF中文本的自动替换,一些因素已经使得查找相关文本的绘制说明变得困难,还有一些因素使替换这些说明的参数中的字符变得复杂

这里列举的问题并不详尽

查找绘制特定文本的说明 PDF包含内容流,其中包含一系列指令,告诉PDF处理器在哪里绘制内容。PDF中的常规文本由设置当前字体(和字体大小)、设置绘制文本的位置以及实际绘制文本的说明绘制。这与以下内容一样易于理解和搜索:

/TT0 1 Tf
9095TM
(file:///C/Users/Mi/Downloads/converted.txt[10.03.2020 18:43:57])Tj
(此处选择大小为1的字体TT0,然后应用仿射变换将文本缩放9倍并移动到位置(5,5),最后是文本“file:///C/Users/Mi/Downloads/converted.txt [10.03.2020 18:43:57]“已绘制。)

在这种情况下,搜索负责绘制给定文本的说明是很容易的。但相关说明也可能看起来有所不同

分割线 例如,字符串可能是以片段形式绘制的,而不是上面的Tj指令,我们可能有

[(file:///C/Users/Mi/Downloads/converted.txt)2([10.03.2020 18:43:57])]TJ
(先到这里)file:///C/Users/Mi/Downloads/converted.txt,然后稍微移动文本绘制位置,然后绘制“[10.03.2020 18:43:57]”,两者都使用相同的TJ指令。)

或者你可以看到

(file:///C/Users/Mi/Downloads/converted.txt)Tj
([10.03.2020 18:43:57])Tj
(文本部分以不同的说明绘制。)

此外,文本片段的顺序可能是意外的:

([10.03.2020 18:43:57])Tj
-40天
(file:///C/Users/Mi/Downloads/converted.txt)Tj
(首先绘制日期字符串,然后在绘制日期之前将文本位置向左移动一段时间,然后绘制URL。)

一些PDF制作者分别绘制每个字符,并在两者之间设置整个文本转换:

9095TM
(f) Tj
9009145TM
(i) Tj
9009235TM
(l) Tj