| src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -526,6 +526,176 @@ } /** * æ©å±ï¼è¯»åExcelä¸å¤ä¸ªæå®Sheetçæ°æ® * @param sheetNameList è¦è¯»åçSheetåç§°å表ï¼nullåè¯»åææSheetï¼ * @param is è¾å ¥æµ * @param titleNum æ é¢å ç¨è¡æ° * @return Map<Sheetåç§°, 对åºSheetçæ°æ®å表> */ public Map<String, List<T>> importExcelMultiSheet(List<String> sheetNameList, InputStream is, int titleNum) { Map<String, List<T>> resultMap = new HashMap<>(); try { this.type = Type.IMPORT; this.wb = WorkbookFactory.create(is); // 1. ç¡®å®è¦è¯»åçSheetå表 List<Sheet> sheetsToRead = new ArrayList<>(); if (sheetNameList != null && !sheetNameList.isEmpty()) { // 读åæå®åç§°çSheet for (String sheetName : sheetNameList) { Sheet sheet = wb.getSheet(sheetName); if (sheet != null) { sheetsToRead.add(sheet); } else { log.warn("æå®çSheetåç§°ä¸åå¨ï¼{}", sheetName); } } } else { // è¯»åææSheet int sheetCount = wb.getNumberOfSheets(); for (int i = 0; i < sheetCount; i++) { sheetsToRead.add(wb.getSheetAt(i)); } } // 2. éåæ¯ä¸ªSheetï¼å¤ç¨åæå¯¼å ¥é»è¾ for (Sheet sheet : sheetsToRead) { String sheetName = wb.getSheetName(wb.getSheetIndex(sheet)); // å¤ç¨åææ ¸å¿å¯¼å ¥é»è¾ï¼å ³é®ï¼å°åææ¹æ³æå为å¯å¤ç¨çå 鍿¹æ³ï¼ List<T> sheetData = importExcelBySheet(sheet, titleNum); resultMap.put(sheetName, sheetData); } } catch (Exception e) { log.error("å¯¼å ¥å¤Sheet Excelå¼å¸¸{}", e.getMessage()); throw new UtilException(e.getMessage()); } finally { IOUtils.closeQuietly(is); } return resultMap; } /** * å é¨å¤ç¨æ¹æ³ï¼æ ¹æ®æå®Sheetå¯¹è±¡è¯»åæ°æ®ï¼æååæimportExcelçæ ¸å¿é»è¾ï¼ */ private List<T> importExcelBySheet(Sheet sheet, int titleNum) throws Exception { List<T> list = new ArrayList<T>(); if (sheet == null) { return list; } boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); Map<String, List<PictureData>> pictures = null; if (isXSSFWorkbook) { pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); } else { pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); } int rows = sheet.getLastRowNum(); if (rows > 0) { Map<String, Integer> cellMap = new HashMap<String, Integer>(); Row heard = sheet.getRow(titleNum); for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { Cell cell = heard.getCell(i); if (StringUtils.isNotNull(cell)) { String value = this.getCellValue(heard, i).toString(); cellMap.put(value, i); } else { cellMap.put(null, i); } } List<Object[]> fields = this.getFields(); Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>(); for (Object[] objects : fields) { Excel attr = (Excel) objects[1]; Integer column = cellMap.get(attr.name()); if (column != null) { fieldsMap.put(column, objects); } } for (int i = titleNum + 1; i <= rows; i++) { Row row = sheet.getRow(i); if (isRowEmpty(row)) { continue; } T entity = null; for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) { Object val = this.getCellValue(row, entry.getKey()); entity = (entity == null ? clazz.newInstance() : entity); Field field = (Field) entry.getValue()[0]; Excel attr = (Excel) entry.getValue()[1]; Class<?> fieldType = field.getType(); // 以䏿¯åææ°æ®ç±»å转æ¢ãåå ¸è§£æçé»è¾ï¼å®å ¨å¤ç¨ï¼ if (String.class == fieldType) { String s = Convert.toStr(val); if (s.matches("^\\d+\\.0$")) { val = StringUtils.substringBefore(s, ".0"); } else { String dateFormat = field.getAnnotation(Excel.class).dateFormat(); if (StringUtils.isNotEmpty(dateFormat)) { val = parseDateToStr(dateFormat, val); } else { val = Convert.toStr(val); } } } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) { val = Convert.toInt(val); } else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) { val = Convert.toLong(val); } else if (Double.TYPE == fieldType || Double.class == fieldType) { val = Convert.toDouble(val); } else if (Float.TYPE == fieldType || Float.class == fieldType) { val = Convert.toFloat(val); } else if (BigDecimal.class == fieldType) { val = Convert.toBigDecimal(val); } else if (Date.class == fieldType) { if (val instanceof String) { val = DateUtils.parseDate(val); } else if (val instanceof Double) { val = DateUtil.getJavaDate((Double) val); } } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) { val = Convert.toBool(val, false); } if (StringUtils.isNotNull(fieldType)) { String propertyName = field.getName(); if (StringUtils.isNotEmpty(attr.targetAttr())) { propertyName = field.getName() + "." + attr.targetAttr(); } if (StringUtils.isNotEmpty(attr.readConverterExp())) { val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); } else if (StringUtils.isNotEmpty(attr.dictType())) { if (!sysDictMap.containsKey(attr.dictType() + val)) { String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); sysDictMap.put(attr.dictType() + val, dictValue); } val = sysDictMap.get(attr.dictType() + val); } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { val = dataFormatHandlerAdapter(val, attr, null); } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) { StringBuilder propertyString = new StringBuilder(); List<PictureData> images = pictures.get(row.getRowNum() + "_" + entry.getKey()); for (PictureData picture : images) { byte[] data = picture.getData(); String fileName = FileUtils.writeImportBytes(data); propertyString.append(fileName).append(SEPARATOR); } val = StringUtils.stripEnd(propertyString.toString(), SEPARATOR); } ReflectUtils.invokeSetter(entity, propertyName, val); } } list.add(entity); } } return list; } /** * 对listæ°æ®æºå°å ¶éé¢çæ°æ®å¯¼å ¥å°excel表å * * @param list å¯¼åºæ°æ®éå src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -21,10 +21,14 @@ import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.service.ICommonFileService; import com.ruoyi.sales.service.ISalesLedgerService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; @@ -43,6 +47,7 @@ @RestController @RequestMapping("/sales/ledger") @AllArgsConstructor @Api(tags = "éå®å°è´¦") public class SalesLedgerController extends BaseController { private ISalesLedgerService salesLedgerService; @@ -59,6 +64,18 @@ private ReceiptPaymentMapper receiptPaymentMapper; /** * å¯¼å ¥éå®å°è´¦ */ @Log(title = "å¯¼å ¥éå®å°è´¦", businessType = BusinessType.INSERT) @PostMapping("/import") @ApiOperation("å¯¼å ¥éå®å°è´¦") public AjaxResult importData(@RequestParam("file") @ApiParam(value = "Excelæä»¶", required = true) MultipartFile file) { return salesLedgerService.importData(file); } /** * æ¥è¯¢éå®å°è´¦å表 */ @GetMapping("/list") src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ package com.ruoyi.sales.dto; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedgerProduct; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Date; import java.util.List; /** * @author :yys * @date : 2026/1/19 9:50 */ @Data public class SalesLedgerImportDto extends SalesLedgerProductImportDto{ @Excel(name = "éå®åå·") private String salesContractNo; @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "å½å ¥æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") private Date entryDate; @Excel(name = "ä¸å¡å") private String salesman; @Excel(name = "客æ·åç§°") private String customerName; @Excel(name = "å½å ¥äºº") private String entryPerson; @Excel(name = "夿³¨") private String remarks; @ApiModelProperty(value = "ç¾è®¢æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "ç¾è®¢æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") private Date executionDate; @Excel(name = "ååéé¢") private BigDecimal contractAmount; } src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,78 @@ package com.ruoyi.sales.dto; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; import java.math.BigDecimal; import java.util.Date; /** * @author :yys * @date : 2026/1/19 9:59 */ @Data public class SalesLedgerProductImportDto { @Excel(name = "éå®åå·") private String salesContractNo; /** * 产å大类 */ @Excel(name = "产å大类") private String productCategory; /** * è§æ ¼åå· */ @Excel(name = "è§æ ¼åå·") private String specificationModel; /** * åä½ */ @Excel(name = "åä½") private String unit; /** * æ°é */ @Excel(name = "æ°é") private BigDecimal quantity; /** * ç¨ç */ @Excel(name = "ç¨ç") private BigDecimal taxRate; /** * å«ç¨åä»· */ @Excel(name = "å«ç¨åä»·") private BigDecimal taxInclusiveUnitPrice; /** * å«ç¨æ»ä»· */ @Excel(name = "å«ç¨æ»ä»·") private BigDecimal taxInclusiveTotalPrice; /** * å票类å */ @Excel(name = "å票类å") private String invoiceType; /** * æ¯å¦è´¨æ£ */ @Excel(name = "æ¯å¦è´¨æ£", readConverterExp = "0=å¦,1=æ¯") private Boolean isChecked; } src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -129,16 +129,16 @@ private BigDecimal futureTicketsAmount=BigDecimal.ZERO; @ApiModelProperty(value = "å¼ç¥¨æ°") private BigDecimal invoiceNum; private BigDecimal invoiceNum = BigDecimal.ZERO; @ApiModelProperty(value = "æªå¼ç¥¨æ°") private BigDecimal noInvoiceNum; private BigDecimal noInvoiceNum = BigDecimal.ZERO; @ApiModelProperty(value = "å¼ç¥¨éé¢") private BigDecimal invoiceAmount; private BigDecimal invoiceAmount = BigDecimal.ZERO; @ApiModelProperty(value = "æªå¼ç¥¨éé¢") private BigDecimal noInvoiceAmount; private BigDecimal noInvoiceAmount = BigDecimal.ZERO; @ApiModelProperty(value = "æ¬æ¬¡å¼ç¥¨æ°") @TableField(exist = false) src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -3,9 +3,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.dto.MonthlyAmountDto; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.pojo.SalesLedger; import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.util.List; @@ -35,4 +37,6 @@ List<MonthlyAmountDto> getAmountHalfYear(Integer type); IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto); AjaxResult importData(MultipartFile file); } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,24 +12,33 @@ import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.account.service.AccountIncomeService; import com.ruoyi.basic.mapper.CustomerMapper; import com.ruoyi.basic.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.other.mapper.TempFileMapper; import com.ruoyi.other.pojo.TempFile; import com.ruoyi.production.dto.ProductStructureDto; import com.ruoyi.production.mapper.*; import com.ruoyi.production.pojo.*; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.sales.dto.MonthlyAmountDto; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.dto.SalesLedgerImportDto; import com.ruoyi.sales.dto.SalesLedgerProductImportDto; import com.ruoyi.sales.mapper.*; import com.ruoyi.sales.pojo.*; import com.ruoyi.sales.service.ISalesLedgerProductService; @@ -44,10 +53,13 @@ import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -130,6 +142,9 @@ private final RedisTemplate<String, String> redisTemplate; @Autowired private ProductModelMapper productModelMapper; @Autowired private ProductMapper productMapper; @Autowired private ProductStructureMapper productStructureMapper; @@ -325,6 +340,99 @@ return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto); } @Autowired private SysUserMapper sysUserMapper; @Override @Transactional(rollbackFor = Exception.class) public AjaxResult importData(MultipartFile file) { LoginUser loginUser = SecurityUtils.getLoginUser(); try { InputStream inputStream = file.getInputStream(); ExcelUtil<SalesLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(SalesLedgerImportDto.class); Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("éå®å°è´¦æ°æ®","éå®äº§åæ°æ®"), inputStream, 0); if(CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("éå®è¡¨æ ¼ä¸ºç©ºï¼"); // ä¸å¡å±åå¹¶ List<SalesLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("éå®å°è´¦æ°æ®"); if(CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("éå®å°è´¦æ°æ®ä¸ºç©ºï¼"); List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("éå®äº§åæ°æ®"); if(CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("éå®äº§åæ°æ®ä¸ºç©ºï¼"); // å®¢æ·æ°æ® List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).toArray(String[]::new))); // è§æ ¼åå·æ°æ® List<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getModel, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getSpecificationModel).toArray(String[]::new))); // 产åå¤§ç±»æ°æ® List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getProductName, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getProductCategory).toArray(String[]::new))); // å½å ¥äººæ°æ® List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getEntryPerson).toArray(String[]::new))); for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) { SalesLedger salesLedger = new SalesLedger(); BeanUtils.copyProperties(salesLedgerImportDto, salesLedger); // éè¿å®¢æ·åç§°æ¥è¯¢å®¢æ·IDï¼å®¢æ·ååå· salesLedger.setCustomerId(customers.stream() .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName())) .findFirst() .map(Customer::getId) .orElse(null)); salesLedger.setCustomerContractNo(customers.stream() .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName())) .findFirst() .map(Customer::getTaxpayerIdentificationNumber) .orElse(null)); Long aLong = sysUsers.stream() .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson())) .findFirst() .map(SysUser::getUserId) .orElse(null); if(aLong == null) throw new RuntimeException("å½å ¥äºº:"+salesLedger.getEntryPerson()+",æ 对åºç¨æ·ï¼"); salesLedger.setEntryPerson(aLong.toString()); salesLedgerMapper.insert(salesLedger); // éå®äº§åæ°æ®ç»å®ï¼éè¿éå®åå·è·å对åºéå®äº§åæ°æ® List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream() .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo())) .collect(Collectors.toList()); if(CollectionUtils.isEmpty(salesLedgerProductImportDtos)) throw new RuntimeException("éå®åå·:"+salesLedgerImportDto.getSalesContractNo()+",æ 对åºäº§åæ°æ®ï¼"); for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) { SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct(); BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct); salesLedgerProduct.setSalesLedgerId(salesLedger.getId()); salesLedgerProduct.setType(1); // 计ç®ä¸å«ç¨æ»ä»· salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP)); salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity()); salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice()); salesLedgerProduct.setProductId(productList.stream() .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory())) .findFirst() .map(Product::getId) .orElse(null)); salesLedgerProduct.setProductModelId(productModels.stream() .filter(productModel -> productModel.getModel().equals(salesLedgerProduct.getSpecificationModel())) .findFirst() .map(ProductModel::getId) .orElse(null)); salesLedgerProduct.setRegister(loginUser.getNickName()); salesLedgerProduct.setRegisterDate(LocalDateTime.now()); salesLedgerProduct.setApproveStatus(0); salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice()); salesLedgerProductMapper.insert(salesLedgerProduct); } } return AjaxResult.success("å¯¼å ¥æå"); }catch (Exception e) { e.printStackTrace(); } return AjaxResult.success("å¯¼å ¥å¤±è´¥"); } // å é¨ç±»ç¨äºåå¨èåç»æ private static class GroupedCustomer { private final Long customerId;