XML 发票解析

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测试结果如下
在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值