@Override
public ResponseBO<ImportPurchaseSettlementLineResp> importPurchaseSettlementLine(MultipartFile file) throws Exception {
ImportPurchaseSettlementLineResp resp = new ImportPurchaseSettlementLineResp();
// 校验
ImportParams params = new ImportParams();
// 表头设置为2行
params.setHeadRows(1);
// 标题行设置为0行,默认是0,可以不设置
params.setTitleRows(1);
// 开启Excel校验
params.setNeedVerify(true);
ExcelImportResult<PomSettlementLineExcelBO> result = ExcelImportUtil.importExcelMore(file.getInputStream(), PomSettlementLineExcelBO.class, params);
List<PomSettlementLineExcelBO> failList = result.getFailList();
List<PomSettlementLineExcelBO> succList = result.getList();
log.info("是否校验失败: " + result.isVerifyFail());
log.info("校验失败的集合:" + failList.size());
log.info("校验通过的集合:" + succList.size());
for(PomSettlementLineExcelBO fail : failList){
String msg = "第" + fail.getSerialNumber() + "行的错误是:" + fail.getErrorMsg();
log.info(msg);
}
for (int i = 0; i < succList.size(); i++) {
PomSettlementLineExcelBO settlementLineBO = succList.get(i);
if(settlementLineBO != null){
//税额+不含税金额 是否 =含税金额
BigDecimal taxAmount = new BigDecimal(StringUtil.isBlank(settlementLineBO.getTaxAmount()) ? "0" : settlementLineBO.getTaxAmount());
BigDecimal noTaxAmount = new BigDecimal(StringUtil.isBlank(settlementLineBO.getNoTaxAmount()) ? "0" : settlementLineBO.getNoTaxAmount());
BigDecimal purchaseTaxAmount = new BigDecimal(StringUtil.isBlank(settlementLineBO.getPurchaseTaxAmount()) ? "0" : settlementLineBO.getPurchaseTaxAmount());
BigDecimal settlementQuantity = new BigDecimal(StringUtil.isBlank(settlementLineBO.getInvoiceQuantity()) ? "0" : settlementLineBO.getInvoiceQuantity());
BigDecimal purchasePrice = new BigDecimal(StringUtil.isBlank(settlementLineBO.getPurchasePrice()) ? "0" : settlementLineBO.getPurchasePrice());
if(taxAmount.add(noTaxAmount).compareTo(purchaseTaxAmount)!=0){
settlementLineBO.setErrorMsg("税额+不含税金额与含税金额不一致");
failList.add(settlementLineBO);
// 从循环中去除
succList.remove(i);
i--;
continue;
}
//开票数量*单价 是否 =含税金额
if(settlementQuantity.multiply(purchasePrice).compareTo(purchaseTaxAmount)!=0){
settlementLineBO.setErrorMsg("开票数量*单价与含税金额不一致");
failList.add(settlementLineBO);
// 从循环中去除
succList.remove(i);
i--;
continue;
}
//效验税务分类枚举
PomSettlementLineReq pomSettlementLineReq = PomSettlementLineReq.copy(settlementLineBO);
pomPurchaseSettlementLineFeignClient.update(pomSettlementLineReq);
}
}
resp.setOver(true);
resp.setResult((succList.size() + failList.size()) > 0);
resp.setSuccess(succList.size());
resp.setFails(failList.size());
resp.setTotal(succList.size() + failList.size());
if(CollectionUtil.isNotEmpty(failList)){
ResponseBO<FileInfoResp> fileInfoResp;
//excel返回错误数据
List<PomSettlementLineErrorExcelResp> errorExcelResps = failList.stream().map(PomSettlementLineExcelBO::copy).collect(Collectors.toList());
int num =0;
for (PomSettlementLineErrorExcelResp errorExcelResp : errorExcelResps) {
num++;
errorExcelResp.setSerialNumber(String.valueOf(num));
}
//Workbook workbook = OfficeExportUtil.getWorkbook(titleText, sheetText, PomSettlementLineErrorExcelResp.class,errorExcelResps);
//查询商品税务表数据
TaxClassificationReq classificationReq = new TaxClassificationReq();
ResponseBO<List<TaxClassificationVO>> taxClassificationResp = pomPurchaseSettlementLineFeignClient.taxClassification(classificationReq);
List<TaxClassificationVO> taxClassificationList = taxClassificationResp.getData();
List<TaxClassificationExcelResp> classificationExcelList = BeanUtil.convert(taxClassificationList, TaxClassificationExcelResp.class);
String titleText = " 错误数据 ";
String sheetText = "【发票系统号码】导出入模板";
//Workbook workbook = OfficeExportUtil.getWorkbook(titleText, sheetText, PomSettlementLineExcelResp.class,settlementLineExcelResps);
ExportParams exportParams1 = new ExportParams(titleText, sheetText);
Map<String, Object> sheet1 = new HashMap<>();
sheet1.put("title", exportParams1);
sheet1.put("entity", PomSettlementLineErrorExcelResp.class);
sheet1.put("data", errorExcelResps);
ExportParams exportParams2 = new ExportParams("商品税务分类", "商品税务分类");
Map<String, Object> sheet2 = new HashMap<>();
sheet2.put("title", exportParams2);
sheet2.put("entity", TaxClassificationExcelResp.class);
sheet2.put("data", classificationExcelList);
List<Map<String, Object>> sheetList = new ArrayList<>();
sheetList.add(sheet1);
sheetList.add(sheet2);
Workbook workbook = ExcelExportUtil.exportExcel(sheetList, ExcelType.HSSF);
Sheet sheet = workbook.getSheetAt(0);
List<String> strings = taxClassificationList.stream().map(TaxClassificationVO::getTaxClassificationName).collect(Collectors.toList());
addValidationToSheet(workbook, sheet, strings.toArray(new String[0]), 'E', 2, 300);
addStyle(failList, workbook, sheet);
addComment(failList, workbook, sheet);
// 隐藏存储下拉列表数据的sheet;可以注释掉该行以便查看、理解存储格式
hideTempDataSheet(workbook, 2);
byte[] bytes = POIUtil.createWorkbook(workbook);
// 上传到oss
UploadFileReq uploadFileReq = new UploadFileReq();
uploadFileReq.setContType("application/msexcel");
uploadFileReq.setInfo(bytes);
uploadFileReq.setFileName("采购发票-" + DateUtil.toDateString(new Date(), "yyyyMMddHHmmssSSS") + ".xls");
fileInfoResp = fileCommonServiceFeign.uploadPublicByte(uploadFileReq);
resp.setErrorFileUrl(fileInfoResp.getData().getUrl());
}
return ResponseUtil.ok(resp);
}
/**
* 增加批注
* @param settlementLineList
* @param workbook
* @param sheet
*/
private void addComment(List<PomSettlementLineExcelBO> settlementLineList, Workbook workbook, Sheet sheet) {
Row row0 = sheet.getRow(0);
Cell cell = row0.getCell(0);
CellStyle style = getBaseCellStyle(workbook);
cell.setCellStyle(style);
CellStyle cellStyle = designComment(workbook);
CellStyle fontStyle = POIUtil.fontBold(workbook);
Row row = sheet.getRow(1);
Cell cell0 = row.getCell(0);
addDraw(sheet, cell0, "序号不能修改", 0);
cell0.setCellStyle(fontStyle);
Cell cell1 = row.getCell(1);
addDraw(sheet, cell1, "采购订单不能修改", 1);
cell1.setCellStyle(fontStyle);
Cell cell2 = row.getCell(2);
addDraw(sheet, cell2, "商品名称不能修改", 2);
cell2.setCellStyle(fontStyle);
Cell cell3 = row.getCell(3);
addDraw(sheet, cell3, "规格型号不能修改", 3);
cell3.setCellStyle(fontStyle);
Cell cell4 = row.getCell(4);
addDraw(sheet, cell4, "税务分类名称,必填", 4);
cell4.setCellStyle(cellStyle);
Cell cell5 = row.getCell(5);
addDraw(sheet, cell5, "商品的开票名称,必填", 5);
cell5.setCellStyle(cellStyle);
Cell cell6 = row.getCell(6);
addDraw(sheet, cell6, "单位不要变动", 6);
cell6.setCellStyle(fontStyle);
Cell cell7 = row.getCell(7);
addDraw(sheet, cell7, "发票的开票单位", 7);
cell7.setCellStyle(cellStyle);
Cell cell8 = row.getCell(8);
addDraw(sheet, cell8, "单价类型不能修改", 8);
cell8.setCellStyle(fontStyle);
Cell cell9 = row.getCell(9);
addDraw(sheet, cell9, "开票量不能修改", 9);
cell9.setCellStyle(fontStyle);
//税率
Cell cell10 = row.getCell(10);
cell10.setCellStyle(cellStyle);
addDraw(sheet, cell10, "整数", 10);
//单价(含税/元)
Cell cell11 = row.getCell(11);
addDraw(sheet, cell11, "最多支持到两位小数", 11);
cell11.setCellStyle(cellStyle);
//不含税金额(元)
Cell cell12 = row.getCell(12);
addDraw(sheet, cell12, "最多支持到两位小数", 12);
cell12.setCellStyle(cellStyle);
//税额(元)
Cell cell13 = row.getCell(13);
cell13.setCellStyle(cellStyle);
addDraw(sheet, cell13, "最多支持到两位小数", 13);
//含税金额(元)
Cell cell14 = row.getCell(14);
addDraw(sheet, cell14, "含税金额不能修改", 14);
cell14.setCellStyle(fontStyle);
Cell cell15 = row.getCell(15);
addDraw(sheet, cell15, "商品单价不能修改", 15);
cell15.setCellStyle(fontStyle);
Cell cell16 = row.getCell(16);
addDraw(sheet, cell16, "发货单不能修改", 16);
cell16.setCellStyle(fontStyle);
Cell cell17 = row.getCell(17);
addDraw(sheet, cell17, "发货明细不能修改", 17);
cell17.setCellStyle(fontStyle);
Cell cell18 = row.getCell(18);
cell18.setCellStyle(cellStyle);
addDraw(sheet, cell18, "限50个文本以内", 18);
Cell cell19 = row.getCell(19);
addDraw(sheet, cell19, "采购发票ID不能修改", 19);
cell19.setCellStyle(fontStyle);
Cell cell20 = row.getCell(20);
addDraw(sheet, cell20, "采购发票子项ID不能修改", 20);
cell20.setCellStyle(fontStyle);
}
private static final short FONT_TEN = 10;
private static final short FONT_TEN_BIG = 10;
/**
* 设置单元格样式
* @param workbook Excel文本对象
* @return
*/
public static CellStyle designComment(Workbook workbook){
//创建单元格样式
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.CENTER);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
style.setWrapText(true);
//创建文本样式
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(true);
//字体大小
font.setFontHeightInPoints(FONT_TEN);
font.setColor(IndexedColors.RED.getIndex());
style.setFont(font);
//设置背景色
style.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
/**
* 增加批注
* @param sheet
* @param cell
* @param name
* @param rowIndex
*/
private void addDraw(Sheet sheet, Cell cell, String name, int rowIndex) {
if(name == null){
cell.removeCellComment();
return;
}
Drawing drawing = sheet.createDrawingPatriarch();
CreationHelper factory = sheet.getWorkbook().getCreationHelper();
ClientAnchor anchor = factory.createClientAnchor();
anchor.setCol1(0);
anchor.setCol2(2);
anchor.setRow1(0);
anchor.setRow2(2);
anchor.setDx1(0);
anchor.setDy1(0);
anchor.setDy2(0);
anchor.setDx2(0);
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
Comment comment = drawing.createCellComment(anchor);
RichTextString str = factory.createRichTextString(name);
comment.setString(str);
comment.setAuthor("Auto+");
comment.setRow(3);
cell.setCellComment(comment);
}
/**
* 基础样式
*
* @return
*/
public static CellStyle getBaseCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.LEFT);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//创建文本样式
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(true);
font.setFontHeightInPoints(FONT_TEN_BIG);
font.setColor(IndexedColors.RED.getIndex());
style.setFont(font);
//设置自动换行
style.setWrapText(true);
return style;
}
/**
* 增加样式
* @param settlementLineList
* @param workbook
* @param sheet
*/
private void addStyle(List<PomSettlementLineExcelBO> settlementLineList, Workbook workbook, Sheet sheet) {
CellStyle cellStyle = POIUtil.designStyles(workbook);
for(int b = 2;b < settlementLineList.size()+2;b++){
Row row = sheet.getRow(b);
Cell cell4 = row.getCell(4);
cell4.setCellStyle(cellStyle);
Cell cell5 = row.getCell(5);
cell5.setCellStyle(cellStyle);
Cell cell7 = row.getCell(7);
cell7.setCellStyle(cellStyle);
//税率
Cell cell10 = row.getCell(10);
cell10.setCellStyle(cellStyle);
//单价(含税/元)
Cell cell11 = row.getCell(11);
cell11.setCellStyle(cellStyle);
//不含税金额(元)
Cell cell12 = row.getCell(12);
cell12.setCellStyle(cellStyle);
int j = b + 1;
cell12.setCellFormula("ROUND((O"+ j +")/(1+K"+ j +"/100), 2)");
//税额(元)
Cell cell13 = row.getCell(13);
cell13.setCellStyle(cellStyle);
cell13.setCellFormula("ROUND(O"+ j + "-M"+ j + ", 2)");
//含税金额(元)
Cell cell14 = row.getCell(14);
cell14.setCellFormula("ROUND(J" + j + "*L" + j + ", 2)");
Cell cell18 = row.getCell(18);
cell18.setCellStyle(cellStyle);
}
}
/**
* 给sheet页,添加下拉列表
*
* @param workbook excel文件,用于添加Name
* @param targetSheet 级联列表所在sheet页
* @param options 级联数据 ['百度','阿里巴巴']
* @param column 下拉列表所在列 从'A'开始
* @param fromRow 下拉限制开始行
* @param endRow 下拉限制结束行
*/
public static void addValidationToSheet(Workbook workbook, Sheet targetSheet, String[] options, char column, int fromRow, int endRow) {
String hiddenSheetName = "sheet" + workbook.getNumberOfSheets();
Sheet optionsSheet = workbook.createSheet(hiddenSheetName);
String nameName = column + "_parent";
int rowIndex = 0;
for (Object option : options) {
int columnIndex = 0;
Row row = optionsSheet.createRow(rowIndex++);
Cell cell = row.createCell(columnIndex++);
cell.setCellValue(option.toString());
}
createName(workbook, nameName, hiddenSheetName + "!$A$1:$A$" + options.length);
DVConstraint constraint = DVConstraint.createFormulaListConstraint(nameName);
CellRangeAddressList regions = new CellRangeAddressList(fromRow, endRow, (int) column - 'A', (int) column - 'A');
targetSheet.addValidationData(new HSSFDataValidation(regions, constraint));
}
/**
* 隐藏excel中的sheet页
*
* @param workbook
* @param start 需要隐藏的 sheet开始索引
*/
private static void hideTempDataSheet(Workbook workbook, int start) {
for (int i = start; i < workbook.getNumberOfSheets(); i++) {
workbook.setSheetHidden(i, true);
}
}
private static Name createName(Workbook workbook, String nameName, String formula) {
Name name = workbook.createName();
name.setNameName(nameName);
name.setRefersToFormula(formula);
return name;
}
@Override
public ResponseBO<List<TaxClassificationVO>> taxClassificationList(TaxClassificationReq req) {
return pomPurchaseSettlementLineFeignClient.taxClassificationList(req);
}
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
@Slf4j
public class POIUtil {
private static final short FONT_TEN = 10;
/**
* 创建xls文本
* @return
*/
/**
* 创建xls文本
* @return
*/
public static byte[] createWorkbook(Workbook workbook){
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()){
workbook.write(bos);
return bos.toByteArray();
} catch (IOException e) {
log.error(e.getMessage());
}
return null;
}
/**
* 设置单元格样式
* @param workbook Excel文本对象
* @return
*/
public static CellStyle designStyles(Workbook workbook){
//创建单元格样式
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.CENTER);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
style.setWrapText(true);
//创建文本样式
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(false);
//字体大小
font.setFontHeightInPoints(FONT_TEN);
style.setFont(font);
//设置背景色
style.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
/**
* 设置单元格样式
* @param workbook Excel文本对象
* @return
*/
public static CellStyle fontBold(Workbook workbook){
//创建单元格样式
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.CENTER);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
style.setWrapText(true);
//创建文本样式
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(true);
style.setFont(font);
return style;
}
}
import java.io.Serializable;
import java.math.BigDecimal;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PomSettlementLineErrorExcelResp implements Serializable {
/**
* 序号
*/
@Excel(name = "序列")
private String serialNumber;
/**
* 采购订单code : PURCHASE_CONTRACT_HEAD_CODE
*/
@Excel(name = "采购订单", width = 15 , replace = {"-_null", "-_ "})
private String purchaseContractCode;
/**
* 商品名称: STOCK_ITEM_LINE_CODE
*/
@Excel(name = "商品标题", width = 15 , replace = {"-_null", "-_ "})
private String stockItemName;
/**
* 规格型号
*/
@Excel(name = "规格型号", width = 15 , replace = {"-_null", "-_ "})
private String stockItemSpecDesc;
/**
* 商品税务分类
*/
@Excel(name = "*税务分类名称", width = 15 , replace = {"-_null", "-_ "})
private String taxClassification;
/**
* 开票名称
*/
@Excel(name = "*开票名称", width = 15 , replace = {"-_null", "-_ "})
private String itemInvoiceName;
/**
* 商品计量单位 : STOCK_UNIT_TYPE
*/
@Excel(name = "单位", width = 15 , replace = {"-_null", "-_ "})
private String stockUnitType;
/**
* 发票计量单位 : INVOICE_UNIT_TYPE
*/
@Excel(name = "开票单位", width = 15 , replace = {"-_null", "-_ "})
private String invoiceUnitType;
/**
* 税率类型 : TAX_CODE_TYPE
*/
@Excel(name = "单价类型", width = 15 , replace = {"-_null", "-_ "})
private String taxCodeType;
/**
* 已开票量
*/
@Excel(name = "开票量", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal invoiceQuantity;
/**
* 税码 : TAX_TYPE
*/
@Excel(name = "税率(%)", width = 15 , replace = {"-_null", "-_ "})
private String taxCode;
/**
* 单价
*/
@Excel(name = "*单价(含税/元)", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal invoicePrice;
/**
* 不含税金额 : NO_TAX_AMOUNT
*/
@Excel(name = "*不含税金额(元)", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal noTaxAmount;
/**
* 税额 : TAX_AMOUNT
*/
@Excel(name = "*税额(元)", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal taxAmount;
/**
* 商品含税金额
*/
@Excel(name = "含税金额(元)", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal purchaseTaxAmount;
/**
* 商品单价
*/
@Excel(name = "商品单价(元)", width = 15, numFormat="0.00", type = 10, replace = {"_null", "_ "})
private BigDecimal purchasePrice;
/**
* 出库单号
*/
@Excel(name = "发货单", width = 15 , replace = {"-_null", "-_ "})
private String deliveryOrderNo;
/**
* 发货单明细Code
*/
@Excel(name = "发货单明细", width = 15 , replace = {"-_null", "-_ "})
private String consignmentLotCode;
/**
* 备注
*/
@Excel(name = "备注", width = 15 , replace = {"-_null", "-_ "})
private String settlementLineRemark;
/**
* 采购发票id
*/
@Excel(name = "采购发票id", width = 15 , replace = {"-_null", "-_ "})
private String purchaseSettlementHeadId;
/**
* 采购发票子项id : PURCHASE_SETTLEMENT_LINE_ID
*/
@Excel(name = "采购发票子项id", width = 15 , replace = {"-_null", "-_ "})
private String purchaseSettlementLineId;
/**
* 错误信息
*/
@Excel(name = "错误信息", width = 15 , replace = {"-_null", "-_ "})
private String errorMsg;
}