@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;@Slf4jpublic 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@Setterpublic 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;}