【发布时间】:2016-01-12 09:17:55
【问题描述】:
我一直在努力解决与 PDFBox 和 PDF 编辑相关的问题。我被分配了编辑给定 PDF 文件的几个字符串的任务,并将已编辑字符串的文件的镜像版本输出到其中。有人告诉我,过去使用这个工具已经解决了这个问题,所以有人告诉我也这样做。我正在使用的功能是这样的:
public void doIt( String inputFile, String outputFile, String strToFind, String message)
throws IOException, COSVisitorException
{
// the document
PDDocument doc = null;
try
{
doc = PDDocument.load( inputFile );
List pages = doc.getDocumentCatalog().getAllPages();
for( int i=0; i<pages.size(); i++ )
{
PDPage page = (PDPage)pages.get( i );
PDStream contents = page.getContents();
PDFStreamParser parser = new PDFStreamParser(contents.getStream() );
parser.parse();
List tokens = parser.getTokens();
for( int j=0; j<tokens.size(); j++ )
{
Object next = tokens.get( j );
if( next instanceof PDFOperator )
{
PDFOperator op = (PDFOperator)next;
//Tj and TJ are the two operators that display
//strings in a PDF
if( op.getOperation().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();
string = string.replaceFirst( strToFind, message );
previous.reset();
previous.append( string.getBytes("ISO-8859-1") );
}
else if( op.getOperation().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();
string = string.replaceFirst( strToFind, message );
cosString.reset();
cosString.append( string.getBytes("ISO-8859-1") );
}
}
}
}
}
//now that the tokens are updated we will replace the
//page content stream.
PDStream updatedStream = new PDStream(doc);
OutputStream out = updatedStream.createOutputStream();
ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
tokenWriter.writeTokens( tokens );
page.setContents( updatedStream );
}
doc.save( outputFile );
}
finally
{
if( doc != null )
{
doc.close();
}
}
}
PDFBox 示例 (https://svn.apache.org/repos/asf/pdfbox/tags/1.5.0/pdfbox/src/main/java/org/apache/pdfbox/examples/pdmodel/ReplaceString.java) 中包含的文件中使用的代码是什么。
然而,我得到的文件根本没有被这个函数修改。什么都没有发生。经过进一步检查,我决定分析解析器生成的标记的顺序。除了 COSString 元素之外,该文件的所有内容都被正确解析,这些元素包含看起来像是被错误编码的乱码(一堆随机符号和数字)。我尝试解析其他文档,并且该函数适用于其中一些文档,但不适用于我作为输入传递的所有内容(乳胶输出文件已正确修改并已正确编码 COSStrings,而其他自动生成的 pdf 没有产生带有乱码 COSString 内容的结果) .我也相当确定结构的其余部分被正确读取,因为我在不同的文件上重建输出,并且输出文件看起来与输入完全相同,这似乎意味着文件结构正在被正确分析。该文件包含 Identity-H 编码的字体。
我尝试使用 PDFTextStripper(从 PDF 中提取文本)解析相同的文件,然后从那里解析输出返回正确的文本输出,使用以下方法:
PDFTextStripper pdfStripper = new PDFTextStripper("UTF-8");
String result = pdfStripper.getText(doc);
System.out.println(result);
可能是编码问题?我可以告诉 PDFStreamParser(或负责的人)在读取时强制编码吗?由于文本提取工作正常,这甚至是编码问题吗?
提前感谢您的帮助。
【问题讨论】:
标签: java parsing pdf encoding pdfbox