文章目录
- 1. xml 类型发票格式
- 2. 数据提取思路
- 2.1 项目结构
- 3. 提取实现
- 3.1 实体类
- 3.2 提取工具类
- 3.3 controller
- 3.4 service
- 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测试结果如下