一、OFD

OFD(Open Fixed-layout Document) ,是由工业和信息化部软件司牵头中国电子技术标准化研究院成立的版式编写组制定的版式文档国家标准,属于中国的一种自主格式,要打破政府部门和党委机关电子公文格式不统一,以方便地进行电子文档的存储、读取以及编辑。

二、OFD格式发票解析

ofd文件类似与zip,解析思路是将其解压之后,然后对其中的xml文件进行处理,可以用dom4j,根据需要选择要处理的xml

OFD.XML

<?xml version="1.0" encoding="UTF-8"?>-<ofd:OFD Version="1.1" DocType="OFD" xmlns:ofd="http://www.ofdspec.org/2016">-<ofd:DocBody>-<ofd:DocInfo><ofd:DocID>605a0643270f4874b54b541369ea24f7</ofd:DocID><ofd:Author>China Tax</ofd:Author><ofd:CreationDate>2020-09-10</ofd:CreationDate>-<ofd:CustomDatas><ofd:CustomData Name="template-version">1.0.20.0422</ofd:CustomData><ofd:CustomData Name="native-producer">SuwellFormSDK</ofd:CustomData><ofd:CustomData Name="producer-version">1.0.20.0603</ofd:CustomData><ofd:CustomData Name="发票代码">033022000313</ofd:CustomData><ofd:CustomData Name="发票号码">00000001</ofd:CustomData><ofd:CustomData Name="合计税额">11283.71</ofd:CustomData><ofd:CustomData Name="合计金额">86797.75</ofd:CustomData><ofd:CustomData Name="开票日期">2020年09月01日</ofd:CustomData><ofd:CustomData Name="校验码">11058 76307 04808 54113</ofd:CustomData><ofd:CustomData Name="购买方纳税人识别号">913302127995019136</ofd:CustomData><ofd:CustomData Name="销售方纳税人识别号">91330203MA2H7WU45J</ofd:CustomData></ofd:CustomDatas></ofd:DocInfo><ofd:DocRoot>Doc_0/Document.xml</ofd:DocRoot><ofd:Signatures>Doc_0/Signs/Signatures.xml</ofd:Signatures></ofd:DocBody></ofd:OFD>

original_invoice.xml

<?xml version="1.0" encoding="UTF-8"?>-<eInvoice Version="1.0" xmlns:fp="http://www.edrm.org.cn/schema/e-invoice/2019"><fp:DocID>03</fp:DocID><fp:InvoiceCode>033022000313</fp:InvoiceCode><fp:InvoiceNo>00000001</fp:InvoiceNo><fp:TypeCode>0</fp:TypeCode><fp:IssueDate>2020年09月01日</fp:IssueDate><fp:InvoiceCheckCode>11058763070480854113</fp:InvoiceCheckCode><fp:MachineNo>667900296527</fp:MachineNo><fp:TaxControlCode>00945*1<0-3>2*62377>93158<5< <4024141+0091580+/30920879<8 4+3-*<3><21/723494/+/+01+225 0*6220933>43/501+<>71+>>><7/ </fp:TaxControlCode>-<fp:Buyer><fp:BuyerName>雅戈尔服装控股有限公司</fp:BuyerName><fp:BuyerTaxID>913302127995019136</fp:BuyerTaxID><fp:BuyerAddrTel>宁波市海曙区鄞县大道西段2号0574-87425577</fp:BuyerAddrTel><fp:BuyerFinancialAccount>农行宁波雅戈尔分理处39428001040000723</fp:BuyerFinancialAccount></fp:Buyer><fp:Tpvn/>-<fp:Seller><fp:SellerName>宁波狮丹努创客科贸有限公司</fp:SellerName><fp:SellerTaxID>91330203MA2H7WU45J</fp:SellerTaxID><fp:SellerAddrTel>浙江省宁波市海曙区吴家路83号1-987457828</fp:SellerAddrTel><fp:SellerFinancialAccount>宁波银行海曙支行20010122000732464</fp:SellerFinancialAccount><fp:Issuea1/><fp:Issuea2/></fp:Seller><fp:TaxInclusiveTotalAmount>98081.46</fp:TaxInclusiveTotalAmount><fp:Note/><fp:InvoiceClerk>管理员</fp:InvoiceClerk><fp:Payee>管理员</fp:Payee><fp:Checker>管理员</fp:Checker><fp:TaxTotalAmount>11283.71</fp:TaxTotalAmount><fp:TaxExclusiveTotalAmount>86797.75</fp:TaxExclusiveTotalAmount><fp:GraphCode>01,20,033022000313,00000001,86797.75,20200901,11058763070480854113,BCB8,</fp:GraphCode><fp:InvoiceSIA1/><fp:InvoiceSIA2/><fp:Signature>MIIBBQYKKoEcz1UGAQQCAqCB9jCB8wIBATEOMAwGCCqBHM9VAYMRBQAwDAYKKoEcz1UGAQQCATGBzzCBzAIBATBjMFgxCzAJBgNVBAYTAkNOMRswGQYDVQQLDBLlm73lrrbnqI7liqHmgLvlsYAxLDAqBgNVBAMMI+eojuWKoeeUteWtkOivgeS5pueuoeeQhuS4reW/gyhTTTIpAgdEAwAAATl1MAwGCCqBHM9VAYMRBQAwDAYIKoEcz1UBg3UFAARGMEQCIGROWCbe2SVfGU8rXl9DTutArClYOxNJVt2bu6RMBW/PAiBoYhg/z8uTptlM+3Qqs1FUMxn37Puo4ii4TLdD+ah+cw==</fp:Signature>-<fp:GoodsInfos>-<fp:GoodsInfo><fp:Item>*纺织产品*200g/m2 100%羊毛1*1罗纹</fp:Item><fp:Specification>262815-6557</fp:Specification><fp:MeasurementDimension>KG</fp:MeasurementDimension><fp:Price>267.070006807352</fp:Price><fp:Quantity>325</fp:Quantity><fp:Amount>86797.75</fp:Amount><fp:TaxScheme>13%</fp:TaxScheme><fp:TaxAmount>11283.71</fp:TaxAmount></fp:GoodsInfo></fp:GoodsInfos></eInvoice>

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import com.data.model.Invoice;/*** * 发票ofd解析util.<br>* * @author qianxiangyun <br>* @version 1.0.0 2021年7月13日<br>* @see* @since JDK 1.5.0*/
public final class InvoiceOfdUtil {/*** 构造方法.*/private InvoiceOfdUtil() {}/*** 日期格式化.*/static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); // 注意月份是MMpublic static void main(final String[] args) {// 1.解压ofd文件try {final String xmlPath = unzip("C:\\Users\\qxy\\Desktop\\033022000313_00000001.ofd");final SAXReader reader = new SAXReader();Document doc;try {doc = reader.read(new File(xmlPath));final Element rootElement = doc.getRootElement(); // 获取document对象根节点,即最外层节点下的内容// 发票代码、发票号码、Invoice invoice = new Invoice();invoice = generateInvoice(rootElement, invoice);System.out.println(invoice.getInvoiceCode());} catch (DocumentException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}/*** ofd发票文件解析.* @param filePath filePath* @return Invoice*/public static Invoice parseOfd(final String filePath) {// 发票代码、发票号码、Invoice invoice = new Invoice();try {final String xmlPath = unzip(filePath);final SAXReader reader = new SAXReader();Document doc;try {doc = reader.read(new File(xmlPath));final Element rootElement = doc.getRootElement(); // 获取document对象根节点,即最外层节点下的内容invoice = generateInvoice(rootElement, invoice);System.out.println(invoice.getInvoiceCode());} catch (DocumentException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}return invoice;}/*** 生成发票信息.* @param rootElement rootElement* @param invoice invoice* @return Invoice*/private static Invoice generateInvoice(final Element rootElement, final Invoice invoice) {// 发票代码final Element invoiceCodeElement = rootElement.element("InvoiceCode");// 发票号码final Element invoiceNoElement = rootElement.element("InvoiceNo");// 开票日期final Element issueDateElement = rootElement.element("IssueDate");// 校验码final Element invoiceCheckCodeElement = rootElement.element("InvoiceCheckCode");// 机器编号final Element machineNoElement = rootElement.element("MachineNo");// 密码区final Element taxControlCodeElement = rootElement.element("TaxControlCode");// 购买方final Element buyerElement = rootElement.element("Buyer");// 销售方final Element sellerElement = rootElement.element("Seller");// 税额final Element taxTotalAmountElement = rootElement.element("TaxTotalAmount");// 金额final Element taxExclusiveTotalAmountElement = rootElement.element("TaxExclusiveTotalAmount");// 价税合计final Element taxInclusiveTotalAmountElement = rootElement.element("TaxInclusiveTotalAmount");// 收款人final Element payeeElement = rootElement.element("payee");// 开票人final Element invoiceClerkElement = rootElement.element("InvoiceClerk");// 复核final Element checkerElement = rootElement.element("Checker");if (invoiceCodeElement != null) {invoice.setInvoiceCode(invoiceCodeElement.getText());}if (invoiceNoElement != null) {invoice.setInvoiceNumber(invoiceNoElement.getText());}if (issueDateElement != null && issueDateElement.getText() != null) {Date date = null;try {date = simpleDateFormat.parse(issueDateElement.getText());} catch (ParseException e) {e.printStackTrace();}invoice.setBillingDate(date);}if (invoiceCheckCodeElement != null) {invoice.setCheckCode(invoiceCheckCodeElement.getText());}if (machineNoElement != null) {invoice.setMachineCode(machineNoElement.getText());}if (taxControlCodeElement != null) {invoice.setMmq(taxControlCodeElement.getText());}if (buyerElement != null) {final List<Element> buyerName = buyerElement.elements("BuyerName");final List<Element> buyerTaxID = buyerElement.elements("BuyerTaxID");final List<Element> buyerAddrTel = buyerElement.elements("BuyerAddrTel");final List<Element> buyerFinancialAccount = buyerElement.elements("BuyerFinancialAccount");invoice.setPurchaserName(buyerName.get(0).getText());invoice.setPurchaserTaxNo(buyerTaxID.get(0).getText());invoice.setPurchaserAddressPhone(buyerAddrTel.get(0).getText());invoice.setPurchaserBank(buyerFinancialAccount.get(0).getText());}if (sellerElement != null) {final List<Element> sellerName = sellerElement.elements("SellerName");final List<Element> sellerTaxID = sellerElement.elements("SellerTaxID");final List<Element> sellerAddrTel = sellerElement.elements("SellerAddrTel");final List<Element> sellerFinancialAccount = sellerElement.elements("SellerFinancialAccount");invoice.setSalesName(sellerName.get(0).getText());invoice.setSalesTaxNo(sellerTaxID.get(0).getText());invoice.setSalesAddressPhone(sellerAddrTel.get(0).getText());invoice.setSalesBank(sellerFinancialAccount.get(0).getText());}if (taxTotalAmountElement != null) {invoice.setTotalTax(new BigDecimal(taxTotalAmountElement.getText()));}if (taxExclusiveTotalAmountElement != null) {invoice.setTotalAmount(new BigDecimal(taxExclusiveTotalAmountElement.getText()));}if (taxInclusiveTotalAmountElement != null) {invoice.setTotalAmount(new BigDecimal(taxInclusiveTotalAmountElement.getText()));}if (payeeElement != null) {invoice.setSkr(payeeElement.getText());}if (invoiceClerkElement != null) {invoice.setKpr(invoiceClerkElement.getText());}if (checkerElement != null) {invoice.setFh(checkerElement.getText());}return invoice;}/*** 从字节流写到文件中.* * @param is*            流* @return file*/private static File getFileByBytes(final InputStream is, final String fileName, final String oldFileName) {final String tempPath = System.getProperty("java.io.tmpdir");final File dirFile = new File(tempPath);if (!dirFile.exists()) {dirFile.mkdirs();}final File file = new File(dirFile, fileName); // zip文件需临时存放服务器final File oldFile = new File(dirFile, oldFileName);OutputStream os = null;try {if (!file.exists()) {file.createNewFile();} else {file.delete();file.createNewFile();}if (oldFile.exists()) {file.delete();}os = new FileOutputStream(file);int len;final byte[] buffer = new byte[4096];while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}os.flush();} catch (Exception e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}try {if (os != null) {os.close();}} catch (IOException e) {e.printStackTrace();}}return file;}/*** 解压ofd文件.* @param ofdFile ofdFile* @return ofdFile路径* @throws IOException IOException*/public static String unzip(final String ofdFile) throws IOException {final ZipFile zipFile = new ZipFile(ofdFile);String lastFileName = "";String temp = "";// 循环查找文件final Enumeration entries = zipFile.entries();while (entries.hasMoreElements()) {final ZipEntry zipEntry = (ZipEntry) entries.nextElement();if (!zipEntry.isDirectory()) {String fileFullName = zipEntry.getName();// 若当前文件包含文件夹名称,则直接去文件名称if (fileFullName.indexOf("/") != -1 && fileFullName.indexOf("original_invoice") > -1) {fileFullName = fileFullName.substring(fileFullName.lastIndexOf("/") + 1);lastFileName = fileFullName;final InputStream in = zipFile.getInputStream(zipEntry);final File xmlfile = getFileByBytes(in, fileFullName, lastFileName);temp = xmlfile.toString();}}}zipFile.close();return temp;}
}

ofd 文件发票解析相关推荐

  1. Python通过解压ofd文件获取发票信息

    Python通过解压ofd文件获取发票信息 实际上ofd.docx.xlsx等文件就是一个压缩文件,是可以被解压处理的.所以我们把一个ofd格式的发票文件解压后就可以看到它的目录,如下: 再用谷歌或者 ...

  2. JAVA识别PDF和OFD电子发票并解析为java对象

    上一篇我们说了java实现电子发票中的发票税号等信息识别的几种可用方案,最后博主选取了识别文件二维码的方式,而且文章最后也说了,这种有局限性,去到的信息有限,而且针对OFD格式也得继续想办法,那接下来 ...

  3. 电子发票ofd文件如何转换成pdf格式

    随着OFD的普及和电子发票的应用,越来越多的OFD格式文件出现在我们的生活之中.你可能会问:什么是ofd文件.下列是来自百度百科的词条内容: OFD(Open Fixed-layout Documen ...

  4. Java OFD文件转换,OFD转PDF、图片、SVG、HTML工具类(2.0.0版本之前)

    OFDRW提供了将OFD文档导出为其他格式文档的能力,如导出为图片.SVG.PDF.文本等. OFDRW 转换模块在 2.0.0 之后抽象了多种文档导出接口,使用统一的 API 实现 OFD 文档导出 ...

  5. ofd转成html,基于HTML5的OFD文件在线显示的方法以及装置与流程

    技术特征: 1.一种基于HTML5的OFD文件在线显示的方法,其特征在于:包括如下步骤: 步骤1.服务器端将OFD文件压缩包进行解压,并将解压后得到的OFD文档目录结构映射至HTML5客户端的URL: ...

  6. 如何将OFD文件转成WORD?每天免费用

    一般的电子发票都是ofd格式的,使用起来特别的不方便.那么如何将OFD文件转成WORD编辑呢?今天小编就和大家分享一个最近使用下来体验感不错的在线转换工具,并且每天都可以免费试用,一起来学习下吧. 1 ...

  7. OFD文件转换支持PDF,PNG,GIF,BMP

    OFD文件转换服务可将发票OFD或公文OFD文件转换成PDF或图片,并实现检测发票OFD是否被篡改,文件转换服务以在线的方式将客户的OFD格式文件转换为所需的格式,包括PDF,PNG,GIF,BMP等 ...

  8. OFD文件打开、打印设置,看这篇就够了

    OFD格式是我国国家版式文档格式标准,全称Open Fixed-layout Document 简单来说,OFD格式"Made In China",而PDF格式是由美国公司制定 上 ...

  9. 理票侠打开OFD格式发票步骤

    你知道OFD发票吗?就在前段时间,我就收到了客户发来的这样一张发票,在手机和电脑上都不能打开.后来我看了一下文件的属性,是ofd格式的,在网上查了一下,这是新出的一种发票格式.但是如何打开OFD格式发 ...

  10. 怎么把OFD文件转换成Word?分享轻松转换的方法

    怎么把OFD格式的文件转换成Word文档呢?大家在日常工作中经常会遇见把PDF文件转换成Word,但是如果遇到OFD格式的文件就会不知道怎么转换了,这种格式的文件通常在一些电子发票.电子公文上可以遇到 ...

最新文章

  1. 项目经理都在用什么项目管理工具?
  2. Leetcode970. Powerful Integers强整数
  3. 流量暴涨擒凶记(转)
  4. JAVA Integer进制的转换
  5. 关于js浅拷贝与深拷贝的理解
  6. 最受Linux程序员欢迎的7个代码编辑器的介绍及下载地址
  7. go新手看的开源项目 哪些适合_最近大家都在用 Go 语言玩什么?这几个新的开源项目告诉你...
  8. 英伟达RTX 2080 Ti值得买么?深度学习测试来了!
  9. html自动播放视频不可用muted,html5_videoaudio的autoplay属性失效的解决方法
  10. java接口压力测试
  11. java 字符串转换成gb2312编码格式
  12. postgres的brin索引
  13. 图片怎样编辑文字?分享三个图片编辑修改文字的方法
  14. Mono.Cecil简介与示例
  15. python处理pdf文件的程序_Python处理PDF文档-拆分合并
  16. 如何利用华硕Mesh系统路由器在780平方公尺大的场域架设可靠的WiFi系统?
  17. 人工智能课后作业_python实现广度优先遍历搜索(BFS)(附源码)
  18. Android中.9图片快捷的制作
  19. 驾考科目一:道路交通安全法律、法规和规章
  20. matlab读csv文件

热门文章

  1. IOS 高德地图导航
  2. 内部推荐岗位信息201508
  3. php迅雷地址解析,迅雷地址在线解密–PHP源码
  4. VS2017+海康威视工业相机调用查找不到设备的问题
  5. Quartus II13.0的破解过程
  6. JAVA实现简易文本编辑器设计
  7. nsis升级包_NSIS v3.2.0.1-简易封包工具
  8. 集成电路工艺专题复习
  9. mysql仓库管理软件破解版_Max(TM)仓库管理软件|Max(TM)仓库管理系统下载_v2.0.5.1 MySQL网络版_9号软件下载...
  10. 简单又实用的MRP手机平台下软件及游戏破解方法