XML 发票解析

文章目录

  • [1. xml 类型发票格式](#1. xml 类型发票格式)
  • [2. 数据提取思路](#2. 数据提取思路)
    • [2.1 项目结构](#2.1 项目结构)
  • [3. 提取实现](#3. 提取实现)
    • [3.1 实体类](#3.1 实体类)
    • [3.2 提取工具类](#3.2 提取工具类)
    • [3.3 controller](#3.3 controller)
    • [3.4 service](#3.4 service)
  • [4. 结果展示](#4. 结果展示)

1. xml 类型发票格式

本文解析的xml类型的发票格式如下

2. 数据提取思路

通过遍历xml文件中的标签去获得标签对应的文本

2.1 项目结构

3. 提取实现

3.1 实体类

Invoice

package com.example.xml.entity;

import lombok.Data;

import java.util.Date;

@Data
public class Invoice {
    private String invoiceNumber; // 发票号码
    private Date invoiceDate; // 开票日期
    private String totalAmount;// 总开票金额
    private String invoiceRemarks;// 发票备注
}

3.2 提取工具类

package com.example.xml.utils;

import com.example.xml.entity.Invoice;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.springframework.web.multipart.MultipartFile;

public class XmlUtils {
    /**
     * 调用该方法将前端接受到的文件暂存
     *
     * @param file
     */
    public static Invoice parseXmlFile(MultipartFile file) {
        Invoice invoice = new Invoice();
        File tempFilePath=null;
        try {
            // 创建一个临时文件
            Path tempFile = null;
            tempFile = Files.createTempFile("tempPrefix", ".xml");

            tempFilePath = tempFile.toFile();

            // 将MultipartFile的内容写入到临时文件
            try (FileOutputStream fos = new FileOutputStream(tempFilePath)) {
                fos.write(file.getBytes());
            }

            // 使用临时文件的路径来调用你的解析方法
            invoice = extract(tempFilePath);

            // 删除临时文件,或者在某些情况下保留它
//            tempFilePath.delete();

        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
        }finally {
            // 无论是否发生异常,都尝试删除临时文件
            if (tempFilePath != null && !tempFilePath.delete()) {
                // 记录删除失败的情况
                System.err.println("无法删除临时文件: " + tempFilePath.getAbsolutePath());
            }
        }
        // 返回值
        return invoice;
    }

    /**
     * 从一个ZIP 文件中提取特定格式的发票信息,并构建一个 Invoice 对象来存储这些信息
     *
     * @param file
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Invoice extract(File file) throws DocumentException, ParseException {
        Invoice invoice = new Invoice();//创建发票实例
        SAXReader reader = new SAXReader();
        Document document = reader.read(file);// 读取XML文件
        // 获取备注中的部分信息
        Element root = document.getRootElement(); // <EInvoice>
        Element eInvoiceData = root.element("EInvoiceData"); // <EInvoiceData>
        // 备注中的销方信息提取
        Element sellerInformation = eInvoiceData.element("SellerInformation"); // <SellerInformation>
        Element sellerBankName = sellerInformation.element("SellerBankName");
        Element sellerBankAccNum = sellerInformation.element("SellerBankAccNum");
        String sellerBankNameValue="";
        String sellerBankAccNumValue="";
        if(sellerBankName!=null){
            sellerBankNameValue = sellerBankName.getTextTrim();//获取<SellerBankName>的文本内容【销方开户银行】
        }
        if(sellerBankAccNum!=null){
            sellerBankAccNumValue = sellerBankAccNum.getTextTrim();//获取<SellerBankAccNum>的文本内容【销方银行账号】
        }
        // 备注中的购方信息提取
        Element buyerInformation = eInvoiceData.element("BuyerInformation"); // <BuyerInformation>
        Element buyerBankName = buyerInformation.element("BuyerBankName");
        Element buyerBankAccNum = buyerInformation.element("BuyerBankAccNum");
        String buyerBankNameValue="";
        String buyerBankAccNumValue="";
        if(buyerBankName!=null){
            buyerBankNameValue = buyerBankName.getTextTrim();//获取<BuyerBankName>的文本内容【购方开户银行】
        }
        if(buyerBankAccNum!=null){
            buyerBankAccNumValue = buyerBankAccNum.getTextTrim();//获取<BuyerBankAccNum>的文本内容【购方银行账号】
        }
        // 开票金额提取
        Element issuItemInformation = eInvoiceData.element("IssuItemInformation"); // <IssuItemInformation>
        Element totalAmount = issuItemInformation.element("TotaltaxIncludedAmount"); // <TotaltaxIncludedAmount>
        String totalAmountValue="";
        if(totalAmount!=null){
            totalAmountValue = totalAmount.getTextTrim();// 获取<TotaltaxIncludedAmount>的文本内容
        }
        // 发票号码
        Element taxSupervisionInfo = root.element("TaxSupervisionInfo"); // <TaxSupervisionInfo>
        Element invoiceNumber = taxSupervisionInfo.element("InvoiceNumber");
        String invoiceNumberValue="";
        if(invoiceNumber!=null){
            invoiceNumberValue = invoiceNumber.getTextTrim();//获取<InvoiceNumber>的文本内容【发票号码】
        }
        //开票日期
        Element issueTime = taxSupervisionInfo.element("IssueTime");
        String issueTimeValue="";
        if(issueTime!=null){
            issueTimeValue = issueTime.getTextTrim();//获取<IssueTime>的文本内容【开票日期】
        }
        //创建Invoice实例,并填充发票信息
        if (invoiceNumberValue != null && invoiceNumberValue != "") {//发票号码
            invoice.setInvoiceNumber(invoiceNumberValue);
        }
        if (issueTimeValue != null && issueTimeValue != "") {//开票日期
            SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date parsedDate = inputDateFormat.parse(issueTimeValue);
            invoice.setInvoiceDate(parsedDate);
        }
        if (totalAmountValue != null && totalAmountValue != "") {// 开票金额
            invoice.setTotalAmount(totalAmountValue);
        }
        //在设置之前排好发票备注的版型
        String note = setNote(buyerBankNameValue, buyerBankAccNumValue, sellerBankNameValue, sellerBankAccNumValue);
        invoice.setInvoiceRemarks(note);


        return invoice;
    }

    /**
     * 拼接备注信息
     *
     * @param buyerBankNameValue    购方开户银行
     * @param buyerBankAccNumValue  购方银行账号
     * @param sellerBankNameValue   销方开户银行
     * @param sellerBankAccNumValue 销方银行账号
     * @return
     */
    public static String setNote(String buyerBankNameValue, String buyerBankAccNumValue, String sellerBankNameValue, String sellerBankAccNumValue) {
        String resultNote = "";
        if (buyerBankNameValue != null && buyerBankNameValue != "") {
            resultNote += "购方开户银行:" + buyerBankNameValue + ";";
        }
        if (buyerBankAccNumValue != null && buyerBankAccNumValue != "") {
            resultNote += "银行账号:" + buyerBankAccNumValue + ";";
        }
        if (sellerBankNameValue != null && sellerBankNameValue != "") {
            resultNote += "销方开户银行:" + sellerBankNameValue + ";";
        }
        if (sellerBankAccNumValue != null && sellerBankAccNumValue != "") {
            resultNote += "银行账号:" + sellerBankAccNumValue + ";";
        }

        return resultNote;
    }

}

3.3 controller

package com.example.xml.controller;

import com.example.xml.entity.Invoice;
import com.example.xml.service.InvoiceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


@RestController
@RequestMapping("/invoice")
public class InvoiceController {
    @Autowired
    InvoiceService invoiceService;

    /**
     * @param
     */
    @CrossOrigin(origins = "http://localhost:8081", allowedHeaders = "*", allowCredentials = "true")
    @PostMapping("/upload")
    public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 调用你的文件解析服务
            Invoice parsedData = invoiceService.parseOfdFile(file);

            // 返回解析后的数据
            return ResponseEntity.ok(parsedData);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error parsing file");
        }
    }
}

3.4 service

InvoiceService

package com.example.xml.service;

import com.example.xml.entity.Invoice;
import org.springframework.web.multipart.MultipartFile;

public interface InvoiceService {
    Invoice parseOfdFile(MultipartFile file);

}

InvoiceServiceImpl

package com.example.xml.service.impl;


import com.example.xml.entity.Invoice;
import com.example.xml.service.InvoiceService;
import com.example.xml.utils.XmlUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
public class InvoiceServiceImpl implements InvoiceService {
    @Override
    public Invoice parseOfdFile(MultipartFile file) {
        Invoice invoice = XmlUtils.parseXmlFile(file);
        return invoice;
    }
}

4. 结果展示

postman测试结果如下

相关推荐
唐叔在学习2 分钟前
【唐叔学算法】第19天:交换排序-冒泡排序与快速排序的深度解析及Java实现
java·算法·排序算法
music0ant6 分钟前
Idea 配置环境 更改Maven设置
java·maven·intellij-idea
任小永的博客10 分钟前
VUE3+django接口自动化部署平台部署说明文档(使用说明,需要私信)
后端·python·django
凡人的AI工具箱13 分钟前
每天40分玩转Django:Django类视图
数据库·人工智能·后端·python·django·sqlite
记得开心一点嘛21 分钟前
Nginx与Tomcat之间的关系
java·nginx·tomcat
凡人的AI工具箱23 分钟前
每天40分玩转Django:实操图片分享社区
数据库·人工智能·后端·python·django
界面开发小八哥33 分钟前
「Java EE开发指南」如何用MyEclipse构建一个Web项目?(一)
java·前端·ide·java-ee·myeclipse
王伯爵36 分钟前
<packaging>jar</packaging>和<packaging>pom</packaging>的区别
java·pycharm·jar
Q_19284999061 小时前
基于Spring Boot的个人健康管理系统
java·spring boot·后端
liutaiyi81 小时前
Redis可视化工具 RDM mac安装使用
redis·后端·macos