【发布时间】:2013-02-12 11:31:08
【问题描述】:
我正在尝试创建一个原型来将 PDF 文件转换为 XML 文件。结果有点奇怪,所有的字符都变成了符号。我认为这个错误是StringBuffer 从字节数组中获取数据的地方。有Java知识的人可以帮忙吗?
此原型软件使用iText API。为了阅读 PDF 文件,我们使用了PDFReader 类。数据首先转换为字节数组,然后使用Stringbuffer,再次转换为字符串。然后我们使用了StreamResult,它作为 XML 转换结果的持有者。
之后,Transformer 类处理来自各种来源的 XML,并将转换输出写入各种接收器。然后TransformerHandler 监听 SAX ContentHandler,解析事件并将其转换为结果。
TransformerHandler 类的startElement() 和endElement() 方法在xml 文件中创建了标签。解析器在 XML 文档中每个元素的开头调用startElement() 方法,在每个元素的结尾调用endElement()。
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class Cp2x {
static StreamResult streamResult;
static TransformerHandler handler;
static AttributesImpl atts;
public static void main(String[] args) throws IOException {
try {
Document document = new Document();
document.open();
PdfReader reader = new PdfReader("C:\\helloworld.pdf");
PdfDictionary page = reader.getPageN(1);
PRIndirectReference objectReference = (PRIndirectReference) page
.get(PdfName.CONTENTS);
PRStream stream = (PRStream) PdfReader
.getPdfObject(objectReference);
byte[] streamBytes = PdfReader.getStreamBytes(stream);
PRTokeniser tokeniser = new PRTokeniser(streamBytes);
StringBuffer string_buffer = new StringBuffer();
while (tokeniser.nextToken()) {
if (tokeniser.getTokenType() == PRTokeniser.TK_STRING) {
string_buffer.append(tokeniser.getStringValue());
}
}
String test = string_buffer.toString();
streamResult = new StreamResult("test.xml");
initXML();
process(test);
closeXML();
document.add(new Paragraph(".."));
document.close();
} catch (Exception e) {
}
}
public static void initXML() throws ParserConfigurationException,
TransformerConfigurationException, SAXException {
SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory
.newInstance();
handler = tf.newTransformerHandler();
Transformer serializer = handler.getTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
serializer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "4");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
handler.setResult(streamResult);
handler.startDocument();
atts = new AttributesImpl();
handler.startElement("", "", "Document", atts);
}
public static void process(String s) throws SAXException {
String[] elements = s.split("\\|");
atts.clear();
handler.startElement("", "", "Note", atts);
handler.characters(elements[0].toCharArray(), 0, elements[0].length());
handler.endElement("", "", "Note");
}
public static void closeXML() throws SAXException {
handler.endElement("", "", "Document");
handler.endDocument();
}
}
【问题讨论】:
-
“结果有点奇怪,所有的字符都变成了符号”似乎是编码问题。在将字节数组转换为字符串时传递编码。根据用例,可以使用 StringBuilder 而不是 StingBuffer。
-
您也忽略了 XObjects 中存在的所有内容;你将如何在 XML 中捕获这些?另外:您只是在阅读 String 对象,并且没有考虑到文本的实际顺序。为什么要使用过时的 iText 版本?当前版本的 iText 具有更好的解析器。它甚至可以使用 TaggedPdfReaderTool 将标记的 PDF 转换为 XML 文件:itextpdf.com/examples/iia.php?id=281(显然只有在您的 PDF 被标记时才会生成 XML)。