系统中有一个读取PDF表单的数据,然后将数据按字段解析出来,存储到数据库的功能。实现思路,大致是先获取PDF的流,把数据导入到xml中,然后逐行读取xml的数据。具体的实现代码有点挫...
package com.rb.common.pdf; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.xml.sax.SAXException; import com.itextpdf.text.DocumentException; import com.rb.owk.commons.lang.base.orm.BusinessException; /** * 解析PDF报表T-Q-1,提取报表数据 * * @author HO274509 * */ public class PdfTQ1 { private PdfTQ1() { } private final static Log log = LogFactory.getLog(PdfTQ1.class); // 要解析的PDF public static final String RESOURCE = "/pdf/T-Q-1.pdf";// classpath相对路径 // 要填充PDF的XML数据来源 public static final String XMLDATA = "T-Q-1.xml"; // 填充之前的PDF public static final String SOURCE = "T-Q-1.pdf"; // 填充之后的PDF public static final String RESULT = "T-Q-1_fill.pdf"; /** * 打印pdf数据 * * @throws TransformerException * @throws TransformerFactoryConfigurationError * @throws SAXException * @throws ParserConfigurationException * @throws IOException */ public static void printPdfData() throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { /** * 获取xml格式数据 */ InputStream in = PdfTQ4.class.getResourceAsStream(RESOURCE); // 另一种获取方法 PdfUtil.getXFAData(RESOURCE, file); ByteArrayOutputStream os = PdfUtil.getXFAData(in); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); /** * 使用dom4j解析xml,获取数据 */ SAXReader xmlReader = new SAXReader(); org.dom4j.Document document = null; try { // document = xmlReader.read(xml); document = xmlReader.read(is); } catch (org.dom4j.DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error("log4j解析出错"); } // 根节点 Element root = document.getRootElement(); // 表单根节点 Element element = root.element("T_Q_1"); // 填报人相关信息 log.info("-----填报人信息-----"); log.info(String.format("填报部门:%s", element.element("FILLIN_DEPT") .getText())); log.info(String.format("填报人:%s", element.element("FILLIN_PERSON") .getText())); log.info(String.format("联系电话:%s", element.element("TELEPHONE") .getText())); log.info(String.format("责任人:%s", element.element("RES_PERSON") .getText())); log.info("-----重要信息系统的停止服务情况-----"); // 表单TQ1001数据根节点:停止服务性质为非预期停止服务的系统停止服务情况 Iterator<Element> it_TQ1001 = element.elementIterator("TQ1001"); int index = 1; while (it_TQ1001.hasNext()) {// 打印非预期停止服务的系统停止服务情况 Element TQ1001 = it_TQ1001.next(); log.info("停止服务性质:非预期停止服务"); log.info(String.format("序号:%s", index)); log .info(String.format("信息系统:%s", TQ1001.element("COL1") .getText())); if (StringUtils.isNotEmpty(TQ1001.elementText("COL2"))) { log.info(String.format("备注:%s", TQ1001.elementText("COL2"))); } log.info(String.format("停止服务原因:%s", TQ1001.elementText("COL3"))); if (StringUtils.isNotEmpty(TQ1001.elementText("COL4"))) { log.info(String.format("备注:%s", TQ1001.elementText("COL4"))); } log.info(String.format("事件等级:%s", TQ1001.elementText("COL5"))); log.info(String.format("起始时间:%s", TQ1001.elementText("COL6"))); log.info(String.format("结束时间:%s", TQ1001.elementText("COL7"))); log.info(String.format("影响范围:%s", TQ1001.elementText("COL8"))); if (StringUtils.isNotEmpty(TQ1001.elementText("COL9"))) { log.info(String.format("个数:%s", TQ1001.elementText("COL9"))); } log.info(String.format("描述:%s", TQ1001.elementText("COL10"))); index++; } // 表单TQ1003数据根节点:停止服务性质为预期停止服务的系统停止服务情况 Iterator<Element> it_TQ1003 = element.elementIterator("TQ1003"); index = 1; while (it_TQ1003.hasNext()) {// 打印停止服务的系统停止服务情况 Element TQ1002 = it_TQ1003.next(); log.info("停止服务性质:预期停止服务"); log.info(String.format("序号:%s", index)); log .info(String.format("信息系统:%s", TQ1002.element("COL1") .getText())); if (StringUtils.isNotEmpty(TQ1002.elementText("COL7"))) { log.info(String.format("备注:%s", TQ1002.elementText("COL7"))); } log.info(String.format("停止服务原因:%s", TQ1002.elementText("COL2"))); if (StringUtils.isNotEmpty(TQ1002.elementText("COL8"))) { log.info(String.format("备注:%s", TQ1002.elementText("COL8"))); } log.info(String.format("起始时间:%s", TQ1002.elementText("COL3"))); log.info(String.format("结束时间:%s", TQ1002.elementText("COL4"))); log.info(String.format("影响范围:%s", TQ1002.elementText("COL10"))); if (StringUtils.isNotEmpty(TQ1002.elementText("COL9"))) { log.info(String.format("个数:%s", TQ1002.elementText("COL9"))); } log.info(String.format("描述:%s", TQ1002.elementText("COL6"))); index++; } // 表单TQ1006数据根节点:核心业务系统重要性能指标 Element TQ1006 = element.element("TQ1006"); log.info("-----核心系统重要性能指标-----"); log.info(String.format("系统可用率-->数量:%s,备注:%s", TQ1006.element("COL1") .getText(), TQ1006.element("COL19").getText())); log.info(String.format("批处理的平均批处理用时-->数量:%s,备注:%s", TQ1006.element( "COL2").getText(), TQ1006.element("COL20").getText())); log.info(String.format("CPU平均使用率-->数量:%s,备注:%s", TQ1006.element("COL3") .getText(), TQ1006.element("COL21").getText())); log.info(String.format("CPU高峰使用率-->数量:%s,备注:%s", TQ1006.element("COL4") .getText(), TQ1006.element("COL22").getText())); log.info(String.format("内存平均使用率-->数量:%s,备注:%s", TQ1006.element("COL5") .getText(), TQ1006.element("COL23").getText())); log.info(String.format("磁盘空间占有率峰值-->数量:%s,备注:%s", TQ1006 .element("COL8").getText(), TQ1006.element("COL26").getText())); log.info(String.format("处理能力---")); log.info(String.format("日均交易笔数-->数量:%s,备注:%s", TQ1006.element("COL9") .getText(), TQ1006.element("COL27").getText())); log.info(String.format("日交易笔数峰值-->数量:%s,备注:%s", TQ1006.element("COL10") .getText(), TQ1006.element("COL28").getText())); log.info(String.format("系统可承载的最大交易并发数-->数量:%s,备注:%s", TQ1006.element( "COL11").getText(), TQ1006.element("COL29").getText())); log.info(String.format("交易成功率-->数量:%s,备注:%s", TQ1006.element("COL12") .getText(), TQ1006.element("COL30").getText())); log.info(String.format("账户数及变动---")); log.info(String.format("公司账户及增减---")); log .info(String.format("公司账户:%s,同比:%s,环比:%s,备注:%s", TQ1006 .element("COL13").getText(), TQ1006.element("COL14") .getText(), TQ1006.element("COL15").getText(), TQ1006 .element("COL31").getText())); log.info(String.format("个人账户及增减---")); log .info(String.format("个人账户:%s,同比:%s,环比:%s,备注:%s", TQ1006 .element("COL16").getText(), TQ1006.element("COL17") .getText(), TQ1006.element("COL18").getText(), TQ1006 .element("COL32").getText())); // 表单TQ1007数据根节点: Element TQ1007 = element.element("TQ1007"); log.info("-----核心网络系统运行情况-----"); log.info(String.format("业务时段平均带宽占用情况(生产中心或中心机房到一级分支机构):%s,备注:%s", TQ1007.elementText("COL1"), TQ1007.elementText("COL15"))); log.info(String.format("业务时段平均带宽占用情况(互联网出口):%s,备注:%s", TQ1007 .elementText("COL2"), TQ1007.elementText("COL16"))); log.info("------网上银行系统运行情况-----"); log.info(String.format("日均交易笔数 数量:%s,备注:%s", TQ1007.elementText("COL3"), TQ1007.elementText("COL17"))); log.info(String.format("日交易笔数峰 数量:%s,备注:%s", TQ1007.elementText("COL4"), TQ1007.elementText("COL18"))); log.info(String.format("系统可承载的最大交易并发 数量:%s,备注:%s", TQ1007 .elementText("COL5"), TQ1007.elementText("COL19"))); log.info(String.format("平均在线并发用户数 数量:%s,备注:%s", TQ1007 .elementText("COL6"), TQ1007.elementText("COL20"))); log.info(String.format("最大在线并发用户数 数量:%s,备注:%s", TQ1007 .elementText("COL7"), TQ1007.elementText("COL21"))); log.info(String.format("系统可承载的最大在线并发数 数量:%s,备注:%s", TQ1007 .elementText("COL8"), TQ1007.elementText("COL22"))); log.info("-----银行卡系统运行情况-----"); log.info(String.format("日均交易笔数 数量:%s,备注:%s", TQ1007.elementText("COL9"), TQ1007.elementText("COL23"))); log.info(String.format("日交易笔数峰数 数量:%s,备注:%s", TQ1007 .elementText("COL10"), TQ1007.elementText("COL24"))); log.info(String.format("系统可承载的最大交易并发数 数量:%s,备注:%s", TQ1007 .elementText("COL11"), TQ1007.elementText("COL25"))); log.info("-----第三方存管系统运行情况-----"); log.info(String.format("日均交易笔数 数量:%s,备注:%s", TQ1007 .elementText("COL12"), TQ1007.elementText("COL26"))); log.info(String.format("日交易笔数峰数 数量:%s,备注:%s", TQ1007 .elementText("COL13"), TQ1007.elementText("COL27"))); log.info(String.format("系统可承载的最大交易并发数 数量:%s,备注:%s", TQ1007 .elementText("COL14"), TQ1007.elementText("COL28"))); log.info("-----数据中心(中心机房)外部异常情况-----"); log.info(String.format("数据中心市电中断次数 数量:%s,备注:%s", TQ1007 .elementText("COL29"), TQ1007.elementText("COL30"))); log.info(String.format("数据中心由于外部原因导致网络通讯中断次数 数量:%s,备注:%s", TQ1007 .elementText("COL31"), TQ1007.elementText("COL32"))); } public static Map<String, Object> getTq1Data() throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { Map<String, Object> tq1Map = new HashMap<String, Object>(); /** * 获取xml格式数据 */ InputStream in = PdfTQ4.class.getResourceAsStream(RESOURCE); ByteArrayOutputStream os = PdfUtil.getXFAData(in); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); /** * 使用dom4j解析xml,获取数据 */ SAXReader xmlReader = new SAXReader(); org.dom4j.Document document = null; try { // document = xmlReader.read(xml); document = xmlReader.read(is); } catch (org.dom4j.DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error("log4j解析出错"); } // PDF报表在adobe life cycle表单设计里的结构是:pdf报表标识符-》多个表单-》表单内嵌套有数据节点或者子表单 // PDF报表的XML数据结构(基本一致,就这四层):ROOT-》报表标识节点-》各个表单根节点=》表单内部数据节点 // 根节点 Element root = document.getRootElement(); // 报表根节点 Element element = root.element("T_Q_1"); // 填报人相关信息 tq1Map.put("ISEMPTY", element.elementText("isempty")); tq1Map.put("FILLINDEPT", element.elementText("FILLIN_DEPT")); tq1Map.put("FILLINPERSON", element.elementText("FILLIN_PERSON")); tq1Map.put("TELEPHONE", element.elementText("TELEPHONE")); tq1Map.put("RESPERSON", element.elementText("RES_PERSON")); List<Map<String, Object>> tq1001List = new ArrayList<Map<String,Object>>(); Iterator<Element> it_TQ1001 = element.elementIterator("TQ1001"); int i=1; while (it_TQ1001.hasNext()) { Element tq1001 = it_TQ1001.next(); Iterator<Element> it = tq1001.elementIterator(); Map<String , Object> tq1001Map = new HashMap<String, Object>(); tq1001Map.put("INDEX", i++); while (it.hasNext()) { Element tmp = it.next(); log.info(tmp.getName() + ":::::::" + tmp.getTextTrim()); tq1001Map.put(tmp.getName(), tmp.getTextTrim()); } if(StringUtils.isEmpty((String)tq1001Map.get("COL9"))){ tq1001Map.put("COL9", null); } tq1001List.add(tq1001Map); } tq1Map.put("tq1001List", tq1001List); List<Map<String, Object>> tq1003List = new ArrayList<Map<String,Object>>(); Iterator<Element> it_TQ1003 = element.elementIterator("TQ1003"); i=1; while (it_TQ1003.hasNext()) { Element tq1003 = it_TQ1003.next(); Iterator<Element> it = tq1003.elementIterator(); Map<String , Object> tq1003Map = new HashMap<String, Object>(); tq1003Map.put("INDEX", i++); while (it.hasNext()) { Element tmp = it.next(); log.info(tmp.getName() + ":::::::" + tmp.getTextTrim()); tq1003Map.put(tmp.getName(), tmp.getTextTrim()); } if(StringUtils.isEmpty((String)tq1003Map.get("COL9"))){ tq1003Map.put("COL9", null); } tq1003List.add(tq1003Map); } tq1Map.put("tq1003List", tq1003List); Element TQ1006 = element.element("TQ1006"); Iterator<Element> it_TQ1006 = TQ1006.elementIterator(); while (it_TQ1006.hasNext()) { Element tmp = it_TQ1006.next(); log.info(tmp.getName() + ":::::::" + tmp.getTextTrim()); tq1Map.put(tmp.getName(), tmp.getTextTrim()); } Element TQ1007 = element.element("TQ1007"); Iterator<Element> it_TQ1007 = TQ1007.elementIterator(); while (it_TQ1007.hasNext()) { Element tmp = it_TQ1007.next(); log.info(tmp.getName()+"TQ1007" + ":::::::" + tmp.getTextTrim()); tq1Map.put(tmp.getName()+"TQ1007", tmp.getTextTrim()); } return tq1Map; } /** * 填充成新的pdf之后,会提示pdf文档自创建后被修改,无法再使用扩展功能,这个不知道为什么 * * @throws IOException * @throws DocumentException */ public static void fillPdf() throws IOException, DocumentException { PdfUtil.manipulatePdf(RESOURCE, XMLDATA, RESULT); } public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException, DocumentException, BusinessException { // 提取pdf数据,打印 printPdfData(); // // 以XML形式导出pdf数据 File file = new File(XMLDATA); PdfUtil.getXFAData(RESOURCE, file); // 根据模板和数据生成PDF fillPdf(); } }
调用的pdfutil代码如下
package com.rb.common.pdf; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.XfaForm; /** * pdf工具类 * 依赖ITEXT * @author HO274509 * */ public class PdfUtil { /** * Reads the data from a PDF containing an XFA form. * 解析基于XML Forms Architecture的pdf,导出xml形式的表单数据写入到文件中 * @param src * the original PDF * @param dest * the data in XML format * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws TransformerFactoryConfigurationError * @throws TransformerException */ public static void getXFAData(String src, File file) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { FileOutputStream os = new FileOutputStream(file); PdfReader reader = new PdfReader(src); XfaForm xfa = new XfaForm(reader); Node node = xfa.getDatasetsNode(); NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { if ("data".equals(list.item(i).getLocalName())) { node = list.item(i); break; } } Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); tf.transform(new DOMSource(node), new StreamResult(os)); reader.close(); } /** * Reads the data from a PDF containing an XFA form. * 解析基于XML Forms Architecture的pdf,导出xml形式的表单数据写入到文件中 * @param src * the original PDF * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws TransformerFactoryConfigurationError * @throws TransformerException */ public static ByteArrayOutputStream getXFAData(InputStream is) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { ByteArrayOutputStream os = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(is); XfaForm xfa = new XfaForm(reader); Node node = xfa.getDatasetsNode(); NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { if ("data".equals(list.item(i).getLocalName())) { node = list.item(i); break; } } Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); tf.transform(new DOMSource(node), new StreamResult(os)); reader.close(); return os; } /** * Reads the data from a PDF containing an XFA form. * 解析基于XML Forms Architecture的pdf,导出xml形式的表单数据写入到文件中 * @param src * the original PDF * @param dest * the data in XML format * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws TransformerFactoryConfigurationError * @throws TransformerException */ public static void getXFAData(InputStream is, File file) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { FileOutputStream os = new FileOutputStream(file); PdfReader reader = new PdfReader(is); XfaForm xfa = new XfaForm(reader); Node node = xfa.getDatasetsNode(); NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { if ("data".equals(list.item(i).getLocalName())) { node = list.item(i); break; } } Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); tf.transform(new DOMSource(node), new StreamResult(os)); reader.close(); } /** * Checks if a PDF containing an interactive form uses AcroForm technology, * XFA technology, or both. Also lists the field names. * * 不支持adobe designer设计的xfa格式的pdf * @param src * the original PDF * @param dest * a text file containing form info. * @throws IOException */ public void getFieldnames(String src, String dest) throws IOException { PrintStream out = new PrintStream(new FileOutputStream(dest)); PdfReader reader = new PdfReader(src); AcroFields form = reader.getAcroFields(); XfaForm xfa = form.getXfa(); out.println(xfa.isXfaPresent() ? "XFA form" : "AcroForm"); Set<String> fields = form.getFields().keySet(); for (String key : fields) { out.println(key); } out.flush(); out.close(); } /** * Reads the XML that makes up an XFA form. * * @param src * the original PDF file * @param dest * the resulting XML file * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws TransformerFactoryConfigurationError * @throws TransformerException */ public void readXfa(String src, String dest) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException { FileOutputStream os = new FileOutputStream(dest); PdfReader reader = new PdfReader(src); XfaForm xfa = new XfaForm(reader); Document doc = xfa.getDomDocument(); Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); tf.transform(new DOMSource(doc), new StreamResult(os)); reader.close(); } /** * Manipulates a PDF file src with the file dest as result * @param src the original PDF * @param xml the XML data that needs to be added to the XFA form * @param dest the resulting PDF * @throws IOException * @throws DocumentException */ public static void manipulatePdf(String src, String xml, String dest) throws IOException, DocumentException { PdfReader reader = new PdfReader(src); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true); AcroFields form = stamper.getAcroFields(); XfaForm xfa = form.getXfa(); xfa.fillXfaForm(new FileInputStream(xml)); stamper.close(); } }
相关推荐
总之,PDF的解析是一项涉及多个层次的技术任务,需要对PDF规范有深入的理解,并能用C++有效地处理二进制数据。通过编写和调试PDF解析器,不仅可以掌握PDF的结构,还能提升C++编程技巧和文件处理能力。
在C++中解析PDF,你需要创建一个解析器来读取PDF的二进制流,并将其转化为可操作的数据结构。这通常涉及到以下步骤: 1. **文件头识别**:PDF文件通常以"%PDF-"开头,这是PDF版本的标识。解析器首先需要识别这个...
B类AIS船载设备通常安装在这些船舶上,它可以根据船舶动态信息的解码过程,通过串口服务器接收并解析AIS报文,为船舶提供实时的位置信息和船舶动态数据,从而提高航行安全。 总结来说,AIS报文解析涉及多个方面,...
标题中的“nmea.rar”指的是一个压缩文件,包含了与NMEA(北美海洋电子...它可能包含理论介绍、代码示例、最佳实践等内容,帮助用户掌握GPS数据解析和处理的技巧,从而开发出能够准确获取和利用GPS信息的应用或系统。
AIS(Automatic Identification System)是一种船舶自动识别系统,主要用于海上航行安全,通过VHF(甚高频)无线电通信网络,...《AIS数据解析.pdf》这份文档很可能会提供详细的步骤和示例,帮助你深入了解这个过程。
1.解析pdf,ofd,扫描图片电子发票数据,选择发票目录批量自动解析,生成解析统计excel文件 2.编辑解析的电子发票内容数据 3.导出打包电子发票数据,发票文件名可以选择多种命名方式 4.pdf相关工具:pdf转图片,ofd转...
美国HIPAA隐私规则对于个人健康医疗数据合规解析.pdf美国HIPAA隐私规则对于个人健康医疗数据合规解析.pdf美国HIPAA隐私规则对于个人健康医疗数据合规解析.pdf美国HIPAA隐私规则对于个人健康医疗数据合规解析.pdf美国...
最近有个项目是要求将PDF版的电子发票,解析成文本格式,要求各个名称都对应,刚开始用的是PDFTextStripper.getText(),发现不能准确的抓到自己想要的数据,后来想了个办法,使用Rectangle,画多个矩形,精准定位,...
Java代码PDF解析成XML是一项技术任务,涉及到Java编程语言、PDF文档处理和XML数据格式转换。在这个场景中,我们主要关注如何使用Java库iTextPDF将PDF文档中的内容解析为XML结构。 首先,我们需要理解PDF(Portable ...
而OFD(Open Financial Document)是我国国家标准规定的电子发票格式,其结构化程度更高,更适合于数据解析。 解析电子发票的核心在于理解其结构和数据标准。PDF和OFD文件内部都包含结构化的数据元素,这些元素按照...
本文将深入探讨如何使用PDFBox库在Java中解析PDF并读取其内容。 PDFBox是Apache软件基金会的一个开源项目,它为Java开发者提供了一系列API来操作PDF文档,包括读取、创建、编辑以及签署PDF等任务。在本示例中,我们...
在Java中解析PDF文件是一项常见的任务,特别是在处理用户提交的文档、数据分析或自动化报告等场景下。本篇文章将深入探讨如何使用Java来解析PDF文件,并提供一个实际的示例。 Java解析PDF主要依赖于第三方库,如...
PDF文件解析是理解PDF文件结构、提取数据或进行编辑操作的关键步骤。在这里,我们将深入探讨如何使用文件流方式来处理PDF文件。 首先,我们需要了解PDF的基本结构。PDF文件由一系列的对象组成,包括页面、字体、...
PDF解析jar包是一种Java开发工具,它包含了处理和解析PDF文档所需的各种类库和方法。在Java编程中,处理PDF文件通常需要借助第三方库,这样的jar包就是其中一种解决方案。PDF(Portable Document Format)是一种通用...
1. 加载和解析PDF文档:PDF.js能够读取PDF文件的元数据,并解析出每个页面的内容。 2. 渲染页面:使用HTML5 Canvas将PDF页面分解为文字、图像、线条等元素,然后在浏览器中逐像素渲染。 3. 缩放和滚动:用户可以平移...
PDF矢量数据解析引擎是一种专门用于处理包含矢量数据的PDF文档的技术,它能够解析PDF文件中的几何形状、线条和曲线,并对其进行操作,如投影转换、裁剪等,以适应不同的应用场景,尤其在地理信息系统(GIS)中显示...
6. **图像和资源管理**:PDF文件中可能包含JPEG、PNG等图像,解析时需要识别并解码这些图像数据。同时,PDF还可能包含其他资源,如颜色空间、渐变和模板。 7. **解析表单和交互元素**:对于包含表单的PDF,解析器还...
本篇文章将详细介绍如何使用Java进行PDF数据的读取,并围绕`PdfReader`这个概念展开。 首先,`PdfReader`通常指的是一个类,存在于某些PDF处理库中,如iText或PDFBox,它的主要功能是打开并解析PDF文件,为后续的...
12.可直接解析指定页的PDF数据,与页面顺序无关。 13.支持日文的处理。 14.支持超级链接的提取。 15.支持直接将PDF文档变为HTM文档。 联系方式: 主页:http://www.pdfimage.com E-mail: pdfimage@pdfimage...