Browse Source

使用elasticsearh

flowtest
zhouhaibin 3 months ago
parent
commit
3879b288ce
  1. 12
      platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/controller/CostTableController.java
  2. 3
      platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/mapper/CostTableMapper.java
  3. 4
      platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/service/CostTableService.java
  4. 154
      platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/service/impl/CostTableServiceImpl.java
  5. 8
      platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/controller/SupplierProductsController.java
  6. 18
      platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/entity/SupplierProducts.java
  7. 14
      platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/service/SupplierProductsService.java
  8. 66
      platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/service/impl/SupplierProductsServiceImpl.java
  9. 91
      platform-boot-starter-demo/src/test/java/tech/abc/platform/support/SerialNoServiceTest.java
  10. 167
      platform-boot-starter-elasticsearch/src/main/java/tech/abc/platform/elasticsearch/entity/SupplierProductsDTO.java
  11. 6
      platform-common/pom.xml
  12. 1
      platform-common/src/main/java/tech/abc/platform/common/base/BaseEntity.java
  13. 5
      platform-common/src/main/java/tech/abc/platform/common/base/BaseMapEntity.java
  14. 231
      platform-common/src/main/java/tech/abc/platform/common/extension/EasyExcelUtils.java
  15. 108
      platform-common/src/main/java/tech/abc/platform/common/extension/ExcelColumnMergeHandler.java
  16. 1
      platform-common/src/main/java/tech/abc/platform/common/extension/ExcelExportExtension.java
  17. 87
      platform-common/src/main/java/tech/abc/platform/common/extension/ExcelRowMergeHandler.java

12
platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/controller/CostTableController.java

@ -23,6 +23,9 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -69,6 +72,15 @@ public class CostTableController extends BaseController {
CostDetailViewVO vo = costTableService.getCostTableDetail(id); CostDetailViewVO vo = costTableService.getCostTableDetail(id);
return ResultUtil.success(vo); return ResultUtil.success(vo);
} }
/**
* 导出单条数据表格文件
*/
@GetMapping("/exportData/{id}")
@SystemLog(value = "-导出造价")
@PreAuthorize("hasPermission(null,'costManagement:costTable:view')")
public void exportData(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
costTableService.exportData(id,response);
}
//region 基本操作 //region 基本操作
/** /**
* 初始化 * 初始化

3
platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/mapper/CostTableMapper.java

@ -3,6 +3,8 @@ package tech.abc.platform.costManagement.mapper;
import tech.abc.platform.costManagement.entity.CostTable; import tech.abc.platform.costManagement.entity.CostTable;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/** /**
* Mapper 接口 * Mapper 接口
@ -12,5 +14,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/ */
public interface CostTableMapper extends BaseMapper<CostTable> { public interface CostTableMapper extends BaseMapper<CostTable> {
} }

4
platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/service/CostTableService.java

@ -4,6 +4,8 @@ import tech.abc.platform.costManagement.entity.CostTable;
import tech.abc.platform.common.base.BaseService; import tech.abc.platform.common.base.BaseService;
import tech.abc.platform.costManagement.vo.CostDetailViewVO; import tech.abc.platform.costManagement.vo.CostDetailViewVO;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,5 +30,7 @@ public interface CostTableService extends BaseService<CostTable> {
CostDetailViewVO getCostTableDetail(String id); CostDetailViewVO getCostTableDetail(String id);
void modifyCostTable(CostDetailViewVO vo); void modifyCostTable(CostDetailViewVO vo);
void exportData(String id,HttpServletResponse response) throws IOException;
} }

154
platform-boot-started-costManagement/src/main/java/tech/abc/platform/costManagement/service/impl/CostTableServiceImpl.java

@ -1,6 +1,15 @@
package tech.abc.platform.costManagement.service.impl; package tech.abc.platform.costManagement.service.impl;
import cn.hutool.core.convert.NumberChineseFormatter;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import tech.abc.platform.common.extension.EasyExcelUtils;
import tech.abc.platform.common.extension.ExcelColumnMergeHandler;
import tech.abc.platform.common.extension.ExcelRowMergeHandler;
import tech.abc.platform.costManagement.entity.CostTable; import tech.abc.platform.costManagement.entity.CostTable;
import tech.abc.platform.costManagement.mapper.CostTableMapper; import tech.abc.platform.costManagement.mapper.CostTableMapper;
import tech.abc.platform.costManagement.service.CostItemDetailService; import tech.abc.platform.costManagement.service.CostItemDetailService;
@ -9,15 +18,17 @@ import tech.abc.platform.common.base.BaseServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import tech.abc.platform.costManagement.vo.CostDetailViewVO; import tech.abc.platform.costManagement.vo.CostDetailViewVO;
import tech.abc.platform.costManagement.vo.CostItemDetailVO; import tech.abc.platform.costManagement.vo.CostItemDetailVO;
import javax.servlet.http.HttpServletResponse;
/** /**
* 服务实现类 * 服务实现类
* *
@ -58,6 +69,65 @@ public class CostTableServiceImpl extends BaseServiceImpl<CostTableMapper, CostT
CostTable costTable = mapperFacade.map(vo, CostTable.class); CostTable costTable = mapperFacade.map(vo, CostTable.class);
updateById(costTable);//修改造价表 updateById(costTable);//修改造价表
} }
@Override
public void exportData(String id, HttpServletResponse response) throws IOException {
//导出数据
//web设置
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String exportFileName = URLEncoder.encode("ces", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportFileName + ".xlsx");
response.setHeader("filename", exportFileName + ".xlsx");
response.setHeader("Access-Control-Expose-Headers", "filename");
//1.查询数据
CostTable costTable = query(id);
List<CostItemDetailVO> costItemDetail = costItemDetailService.getCostItemDetail(costTable.getId());
List<String> heads = new ArrayList<>();
heads.add("序号");
heads.add("费用类型");
heads.add("建设内容");
heads.add("小计(元)");
heads.add("备注");
List<String> childHeads = new ArrayList<>();
childHeads.add("序号");
childHeads.add("设备名称");
childHeads.add("主要技术参数");
childHeads.add("数量");
childHeads.add("单位");
childHeads.add("单价");
childHeads.add("小计");
List<Object> otherCostData = new ArrayList<>();
List<List<Object>> otherCostList= new ArrayList<>();
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
List<List<Object>> dataList = new ArrayList<>();
ExcelColumnMergeHandler columnMergeHandler = new ExcelColumnMergeHandler(1, new int[]{0, 1});
ExcelRowMergeHandler rowMergeHandler = new ExcelRowMergeHandler();
Integer xuhao= 1;
Integer num=0;
for (int i = 0; i < costItemDetail.size(); i++) {
CostItemDetailVO costItemDetailVO = costItemDetail.get(i);
if(StringUtils.isBlank(costItemDetailVO.getCostType())){
List<Object> objects = getChildDataList(costItemDetailVO, i);
otherCostList.add(objects);
continue;
}
List<Object> objectList = getDataList(costItemDetail, i, xuhao);
dataList.add(objectList);
num = setChildDataSheet(costItemDetailVO,excelWriter,num,heads,childHeads,columnMergeHandler,rowMergeHandler);
}
num=num+1;
WriteSheet sheet2 = EasyExcel.writerSheet(num,"未分类费用").head(EasyExcelUtils.head(childHeads)).registerWriteHandler(columnMergeHandler).registerWriteHandler(rowMergeHandler).build();
excelWriter.write(otherCostList, sheet2);
WriteSheet sheet1 = EasyExcel.writerSheet(0, "项目投资概算总表").head(EasyExcelUtils.head(heads)).registerWriteHandler(columnMergeHandler).registerWriteHandler(rowMergeHandler).build();
excelWriter.write(dataList, sheet1);
log.info(num+"个sheet已写入");
excelWriter.finish();
//3.返回结果
}
@Override @Override
public void afterRemove(CostTable entity) { public void afterRemove(CostTable entity) {
costItemDetailService.removeByCostTableId(entity.getId()); costItemDetailService.removeByCostTableId(entity.getId());
@ -92,6 +162,82 @@ public class CostTableServiceImpl extends BaseServiceImpl<CostTableMapper, CostT
@Override @Override
protected void copyPropertyHandle(CostTable entity, String... value) { protected void copyPropertyHandle(CostTable entity, String... value) {
} }
private List<Object> getChildDataList(CostItemDetailVO children, Integer j) {
List<Object> childObject = new ArrayList<>();
childObject.add(NumberChineseFormatter.format(j + 1, false, false));
childObject.add(children.getCostName());
childObject.add(children.getCostDescribe());
childObject.add(children.getQuantity());
childObject.add(children.getUnit());
childObject.add(children.getUnitPrice());
childObject.add(children.getTotalPrice());
return childObject;
}
private List<Object> getDataList(List<CostItemDetailVO> costItemDetail, Integer i, Integer xuhao) {
CostItemDetailVO costItemDetailVO = costItemDetail.get(i);
List<Object> objectList = new ArrayList<>();
if(i>=1){
//比较后一个和前一个是否一样
String newCostType = costItemDetailVO.getCostType();
String lastCostType = costItemDetail.get(i-1).getCostType();
if(!newCostType.equals(lastCostType)) {
xuhao=xuhao+1;
}
}
objectList.add(NumberChineseFormatter.format(xuhao,false,false));
objectList.add(costItemDetailVO.getCostType());
objectList.add(costItemDetailVO.getConstructContent());
objectList.add(costItemDetailVO.getTotalPrice());
objectList.add(costItemDetailVO.getRemarks());
return objectList;
}
/**
* 递归获取子节点数据
* @param costItemDetailVO
* @param num
* @return
*/
private Integer setChildDataSheet(CostItemDetailVO costItemDetailVO,
ExcelWriter excelWriter,
Integer num,
List<String> heads,
List<String> childHeads,
ExcelColumnMergeHandler columnMergeHandler,
ExcelRowMergeHandler rowMergeHandler) {
List<CostItemDetailVO> childrenList = costItemDetailVO.getChildren();
List<List<Object>> childDataList = new ArrayList<>();
Boolean isDetail = true;
for (Integer j = 0; j < childrenList.size(); j++) {
CostItemDetailVO child = childrenList.get(j);
if(child.getIsDetail().equals("1")){
isDetail=true;
List<Object> childObject = getChildDataList(child, j);
childDataList.add(childObject);
List<CostItemDetailVO> childChildren = child.getChildren();
if(childChildren.size()>0){
num = setChildDataSheet(child,excelWriter,num,heads,childHeads,columnMergeHandler,rowMergeHandler);
}
}else{
isDetail=false;
Integer xuhao=1;
List<Object> childObject = getDataList(childrenList, j, xuhao);
childDataList.add(childObject);
List<CostItemDetailVO> childChildren = child.getChildren();
if(childChildren.size()>0){
num = setChildDataSheet(child,excelWriter,num,heads,childHeads,columnMergeHandler,rowMergeHandler);
}
}
} }
num=num+1;
if(!isDetail){
WriteSheet sheet2 = EasyExcel.writerSheet(num,costItemDetailVO.getConstructContent()).head(EasyExcelUtils.head(heads)).registerWriteHandler(columnMergeHandler).registerWriteHandler(rowMergeHandler).build();
excelWriter.write(childDataList, sheet2);
return num;
}
WriteSheet sheet2 = EasyExcel.writerSheet(num,costItemDetailVO.getConstructContent()).head(EasyExcelUtils.head(childHeads)).registerWriteHandler(columnMergeHandler).registerWriteHandler(rowMergeHandler).build();
excelWriter.write(childDataList, sheet2);
return num;
}
}

8
platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/controller/SupplierProductsController.java

@ -98,6 +98,8 @@ public class SupplierProductsController extends BaseController {
@SystemLog(value = "-分页") @SystemLog(value = "-分页")
@PreAuthorize("hasPermission(null,'productManagement:supplierProducts:query')") @PreAuthorize("hasPermission(null,'productManagement:supplierProducts:query')")
public ResponseEntity<Result> page(SupplierProductsVO queryVO, PageInfo pageInfo, SortInfo sortInfo) { public ResponseEntity<Result> page(SupplierProductsVO queryVO, PageInfo pageInfo, SortInfo sortInfo) {
IPage<SupplierProductsVO> pageVO=null;
if (StringUtils.isBlank(queryVO.getProductName())) {
//构造分页对象 //构造分页对象
IPage<SupplierProducts> page = new Page<SupplierProducts>(pageInfo.getPageNum(), pageInfo.getPageSize()); IPage<SupplierProducts> page = new Page<SupplierProducts>(pageInfo.getPageNum(), pageInfo.getPageSize());
@ -108,9 +110,13 @@ public class SupplierProductsController extends BaseController {
//查询数据 //查询数据
supplierProductsService.page(page, queryWrapper); supplierProductsService.page(page, queryWrapper);
//转换vo //转换vo
IPage<SupplierProductsVO> pageVO = mapperFacade.map(page, IPage.class); pageVO = mapperFacade.map(page, IPage.class);
List<SupplierProductsVO> supplierProductsVOList=convert2VO(page.getRecords()); List<SupplierProductsVO> supplierProductsVOList=convert2VO(page.getRecords());
pageVO.setRecords(supplierProductsVOList); pageVO.setRecords(supplierProductsVOList);
}else{
pageVO = supplierProductsService.querypagebyes(queryVO, pageInfo, sortInfo);
}
return ResultUtil.success(pageVO); return ResultUtil.success(pageVO);
} }

18
platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/entity/SupplierProducts.java

@ -2,7 +2,11 @@ package tech.abc.platform.productManagement.entity;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import java.lang.annotation.Documented;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import tech.abc.platform.common.base.BaseEntity; import tech.abc.platform.common.base.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -25,81 +29,95 @@ public class SupplierProducts extends BaseEntity {
* 供应商id * 供应商id
*/ */
@TableField("supplier_information_id") @TableField("supplier_information_id")
@JsonProperty("supplier_information_id")
private String supplierInformationId; private String supplierInformationId;
/** /**
* 厂商产品型号id * 厂商产品型号id
*/ */
@TableField("model_id") @TableField("model_id")
@JsonProperty("model_id")
private String modelId; private String modelId;
/** /**
* 个人产品规格 * 个人产品规格
*/ */
@TableField("product_specifications") @TableField("product_specifications")
@JsonProperty("product_specifications")
private String productSpecifications; private String productSpecifications;
/** /**
* 产品名称 * 产品名称
*/ */
@TableField("product_name") @TableField("product_name")
@JsonProperty("product_name")
private String productName; private String productName;
/** /**
* 产品标识型号 * 产品标识型号
*/ */
@TableField("product_identity") @TableField("product_identity")
@JsonProperty("product_identity")
private String productIdentity; private String productIdentity;
/** /**
* 产品价格 * 产品价格
*/ */
@TableField(value="product_price",updateStrategy= FieldStrategy.IGNORED) @TableField(value="product_price",updateStrategy= FieldStrategy.IGNORED)
@JsonProperty("product_price")
private BigDecimal productPrice; private BigDecimal productPrice;
/** /**
* 信息来源 * 信息来源
*/ */
@TableField("source_information") @TableField("source_information")
@JsonProperty("source_information")
private String sourceInformation; private String sourceInformation;
/** /**
* 备注 * 备注
*/ */
@TableField("remarks") @TableField("remarks")
@JsonProperty("remarks")
private String remarks; private String remarks;
/** /**
* 产品图片 * 产品图片
*/ */
@TableField("image") @TableField("image")
@JsonProperty("image")
private String image; private String image;
/** /**
* 产品品牌 * 产品品牌
*/ */
@TableField("brand") @TableField("brand")
@JsonProperty("brand")
private String brand; private String brand;
/** /**
* 产品单位*/ * 产品单位*/
@TableField("unit") @TableField("unit")
@JsonProperty("unit")
private String unit; private String unit;
/** /**
* 除税价格 * 除税价格
*/ */
@TableField("ex_tax_price") @TableField("ex_tax_price")
@JsonProperty("ex_tax_price")
private BigDecimal exTaxPrice; private BigDecimal exTaxPrice;
/** /**
* 税率 * 税率
*/ */
@TableField("taxrate") @TableField("taxrate")
@JsonProperty("taxrate")
private BigDecimal taxrate; private BigDecimal taxrate;
/** /**
* 分类id * 分类id
*/ */
@TableField("category_id") @TableField("category_id")
@JsonProperty("category_id")
private String categoryId; private String categoryId;
/********非库表存储属性*****/ /********非库表存储属性*****/
} }

14
platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/service/SupplierProductsService.java

@ -1,7 +1,12 @@
package tech.abc.platform.productManagement.service; package tech.abc.platform.productManagement.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import tech.abc.platform.common.vo.PageInfo;
import tech.abc.platform.common.vo.SortInfo;
import tech.abc.platform.productManagement.entity.SupplierProducts; import tech.abc.platform.productManagement.entity.SupplierProducts;
import tech.abc.platform.common.base.BaseService; import tech.abc.platform.common.base.BaseService;
import tech.abc.platform.productManagement.vo.SupplierProductsVO;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -21,5 +26,14 @@ public interface SupplierProductsService extends BaseService<SupplierProducts> {
*/ */
Map<String,String> getNameMap(List<String> idList); Map<String,String> getNameMap(List<String> idList);
/**
* es分页查询
* @param queryVO
* @param pageInfo
* @param sortInfo
* @return
*/
IPage<SupplierProductsVO> querypagebyes(SupplierProductsVO queryVO, PageInfo pageInfo, SortInfo sortInfo);
} }

66
platform-boot-started-productManagement/src/main/java/tech/abc/platform/productManagement/service/impl/SupplierProductsServiceImpl.java

@ -1,7 +1,17 @@
package tech.abc.platform.productManagement.service.impl; package tech.abc.platform.productManagement.service.impl;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import tech.abc.platform.common.vo.PageInfo;
import tech.abc.platform.common.vo.SortInfo;
import tech.abc.platform.elasticsearch.entity.SupplierProductsDTO;
import tech.abc.platform.productManagement.entity.SupplierProductModel; import tech.abc.platform.productManagement.entity.SupplierProductModel;
import tech.abc.platform.productManagement.entity.SupplierProductModelDetails; import tech.abc.platform.productManagement.entity.SupplierProductModelDetails;
import tech.abc.platform.productManagement.entity.SupplierProducts; import tech.abc.platform.productManagement.entity.SupplierProducts;
@ -12,12 +22,17 @@ import tech.abc.platform.productManagement.service.SupplierProductsService;
import tech.abc.platform.common.base.BaseServiceImpl; import tech.abc.platform.common.base.BaseServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.HashMap; import java.util.HashMap;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import tech.abc.platform.productManagement.vo.SupplierProductsVO;
/** /**
* 服务实现类 * 服务实现类
* *
@ -31,6 +46,8 @@ public class SupplierProductsServiceImpl extends BaseServiceImpl<SupplierProduct
private SupplierProductModelMapper supplierProductModelMapper; private SupplierProductModelMapper supplierProductModelMapper;
@Autowired @Autowired
private SupplierProductModelDetailsMapper supplierProductModelDetailsMapper; private SupplierProductModelDetailsMapper supplierProductModelDetailsMapper;
@Autowired
private ElasticsearchClient client;
@Override @Override
public SupplierProducts init() { public SupplierProducts init() {
SupplierProducts entity=new SupplierProducts(); SupplierProducts entity=new SupplierProducts();
@ -76,6 +93,55 @@ public class SupplierProductsServiceImpl extends BaseServiceImpl<SupplierProduct
return result; return result;
} }
@Override
public IPage<SupplierProductsVO> querypagebyes(SupplierProductsVO queryVO, PageInfo pageInfo, SortInfo sortInfo) {
// 执行查询
Page<SupplierProductsVO> supplierProductsVOPage = new Page<>(pageInfo.getPageNum(), pageInfo.getPageSize());
String productName = queryVO.getProductName();
try {
SearchResponse<SupplierProductsDTO> searchResponse = client.search(srBuilder -> srBuilder
.index("pmg_supplier_products")
// MultiMatch 查找:对输入内容先分词再查询。
.query(queryBuilder -> queryBuilder
.multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
.fields("product_name", "product_specifications")
.query(productName)
.operator(Operator.Or)))
//高亮显示
.highlight(highlightBuilder -> highlightBuilder
.preTags("<span style=\"color: red;\">")
.postTags("</span>")
.requireFieldMatch(false) //多字段时,需要设置为false
.fields("product_name", highlightFieldBuilder -> highlightFieldBuilder)
.fields("product_specifications", highlightFieldBuilder -> highlightFieldBuilder)
)
.from(pageInfo.getPageNum()-1)
.size(pageInfo.getPageSize())
, SupplierProductsDTO.class);
List<Hit<SupplierProductsDTO>> hitList = searchResponse.hits().hits();
supplierProductsVOPage.setTotal(searchResponse.hits().total().value());
List<SupplierProductsVO> supplierProductsVOList =new ArrayList<>();
for (Hit<SupplierProductsDTO> hit : hitList) {
SupplierProductsVO supplierProductsVO = new SupplierProductsVO();
BeanUtils.copyProperties(hit.source(),supplierProductsVO);
// SupplierProductsVO map = mapperFacade.map(hit.source(), SupplierProductsVO.class);
if(hit.highlight().get("product_name")!=null){
supplierProductsVO.setProductName(hit.highlight().get("product_name").get(0));
}
if(hit.highlight().get("product_specifications")!=null){
supplierProductsVO.setProductSpecifications(hit.highlight().get("product_specifications").get(0));
}
supplierProductsVOList.add(supplierProductsVO);
}
supplierProductsVOPage.setRecords(supplierProductsVOList);
} catch (IOException e) {
throw new RuntimeException(e);
}
return supplierProductsVOPage;
}
@Override @Override
protected void copyPropertyHandle(SupplierProducts entity, String... value) { protected void copyPropertyHandle(SupplierProducts entity, String... value) {
} }

91
platform-boot-starter-demo/src/test/java/tech/abc/platform/support/SerialNoServiceTest.java

@ -1,12 +1,22 @@
package tech.abc.platform.support; package tech.abc.platform.support;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import tech.abc.platform.boot.PlatformBootApplication; import tech.abc.platform.boot.PlatformBootApplication;
import tech.abc.platform.elasticsearch.entity.SupplierProductsDTO;
import tech.abc.platform.productManagement.entity.SupplierProducts;
import tech.abc.platform.support.service.SerialNoService; import tech.abc.platform.support.service.SerialNoService;
import java.io.IOException;
/** /**
* @author wqliu * @author wqliu
@ -17,6 +27,8 @@ import tech.abc.platform.support.service.SerialNoService;
class SerialNoServiceTest { class SerialNoServiceTest {
@Autowired @Autowired
private SerialNoService serialNoService; private SerialNoService serialNoService;
@Autowired
private ElasticsearchClient client;
@Test @Test
void generateSingleNo() { void generateSingleNo() {
@ -26,12 +38,87 @@ class SerialNoServiceTest {
} }
/**
* 全量数据分页和排序
* @throws IOException
* .sort(sortOptionsBuilder -> sortOptionsBuilder
* .field(fieldSortBuilder -> fieldSortBuilder
* .field("age").order(SortOrder.Desc)
* .field("id").order(SortOrder.Desc))), Map.class);
*
*
* // 执行查询 数据过滤
* SearchResponse<Map> searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
* .index("db_idx4")
* // 执行要返回的字段
* .source(sourceConfigBuilder -> sourceConfigBuilder
* .filter(sourceFilterBuilder -> sourceFilterBuilder
* .includes("id", "name", "age")
* .excludes("age"))), Map.class);
*
* //解析查询结果
* System.out.println(searchResponse);
*/
@Test
void testSendTextMail() throws IOException {
SearchResponse<SupplierProductsDTO> pmgSupplierProducts = client.search(s -> s
.index("pmg_supplier_products")
.from(0)
.size(10).sort(sort->sort.field(f->f.field("id").order(SortOrder.Desc))),
SupplierProductsDTO.class);
for (Hit<SupplierProductsDTO> hit: pmgSupplierProducts.hits().hits()) {
SupplierProductsDTO pd = hit.source();
System.out.println(pd);
}
}
/**
* 单字段分词查询 match在匹配时会对所查找的关键词进行分词然后按分词匹配查找
* @throws IOException
*/
@Test @Test
void testSendTextMail() { void query() throws IOException {
SearchResponse<SupplierProductsDTO> pmgSupplierProducts = client.search(s -> s
.index("pmg_supplier_products")
.query(queryBuilder -> queryBuilder.match(matchBuilder -> matchBuilder.field("product_name").query("计算机显卡")))
.from(0)
.size(10).sort(sort->sort.field(f->f.field("id").order(SortOrder.Desc))),
SupplierProductsDTO.class);
for (Hit<SupplierProductsDTO> hit: pmgSupplierProducts.hits().hits()) {
SupplierProductsDTO pd = hit.source();
System.out.println(pd);
}
} }
/**
* 多字段查询multi_match multi_match 关键字可以根据字段类型决定是否使用分词查询得分最高的在前面
* @throws IOException
*/
@Test @Test
void sendHtmlMail() { void sendHtmlMail() throws IOException {
// 执行查询
SearchResponse<SupplierProductsDTO> searchResponse = client.search(srBuilder -> srBuilder
.index("pmg_supplier_products")
// MultiMatch 查找:对输入内容先分词再查询。
.query(queryBuilder -> queryBuilder
.multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
.fields("product_name", "product_specifications")
.query("电脑显卡主机")
.operator(Operator.Or)))
//高亮显示
.highlight(highlightBuilder -> highlightBuilder
.preTags("<font color='red'>")
.postTags("</font>")
.requireFieldMatch(false) //多字段时,需要设置为false
.fields("product_name", highlightFieldBuilder -> highlightFieldBuilder)
.fields("product_specifications", highlightFieldBuilder -> highlightFieldBuilder)
)
, SupplierProductsDTO.class);
//解析查询结果
System.out.println(searchResponse);
} }
@Test @Test

167
platform-boot-starter-elasticsearch/src/main/java/tech/abc/platform/elasticsearch/entity/SupplierProductsDTO.java

@ -0,0 +1,167 @@
package tech.abc.platform.elasticsearch.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import tech.abc.platform.common.base.BaseEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 实体类
*
* @author ZHB
* @date 2024-05-08
*
*/
@Data
@TableName("pmg_supplier_products")
@JsonIgnoreProperties(ignoreUnknown=true)
public class SupplierProductsDTO {
/**
* 供应商id
*/
@TableField("supplier_information_id")
@JsonProperty("supplier_information_id")
private String supplierInformationId;
/**
* 厂商产品型号id
*/
@TableField("model_id")
@JsonProperty("model_id")
private String modelId;
/**
* 个人产品规格
*/
@TableField("product_specifications")
@JsonProperty("product_specifications")
private String productSpecifications;
/**
* 产品名称
*/
@TableField("product_name")
@JsonProperty("product_name")
private String productName;
/**
* 产品标识型号
*/
@TableField("product_identity")
@JsonProperty("product_identity")
private String productIdentity;
/**
* 产品价格
*/
@TableField(value="product_price",updateStrategy= FieldStrategy.IGNORED)
@JsonProperty("product_price")
private BigDecimal productPrice;
/**
* 信息来源
*/
@TableField("source_information")
@JsonProperty("source_information")
private String sourceInformation;
/**
* 备注
*/
@TableField("remarks")
@JsonProperty("remarks")
private String remarks;
/**
* 产品图片
*/
@TableField("image")
@JsonProperty("image")
private String image;
/**
* 产品品牌
*/
@TableField("brand")
@JsonProperty("brand")
private String brand;
/**
* 产品单位*/
@TableField("unit")
@JsonProperty("unit")
private String unit;
/**
* 除税价格
*/
@TableField("ex_tax_price")
@JsonProperty("ex_tax_price")
private BigDecimal exTaxPrice;
/**
* 税率
*/
@TableField("taxrate")
@JsonProperty("taxrate")
private BigDecimal taxrate;
/**
* 分类id
*/
@TableField("category_id")
@JsonProperty("category_id")
private String categoryId;
/**
* 逻辑删除
*/
@TableField(value = "delete_flag", fill = FieldFill.INSERT)
@TableLogic
@JsonProperty("delete_flag")
protected String deleteFlag;
/**
* 创建人标识
*/
@TableField(value = "create_id", fill = FieldFill.INSERT)
@JsonProperty("create_id")
private String createId;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonProperty("create_time")
private String createTime;
/**
* 更新人标识
*/
@TableField(value = "update_id", fill = FieldFill.INSERT_UPDATE)
@JsonProperty("update_id")
private String updateId;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@JsonProperty("update_time")
private String updateTime;
/**
* 版本
*/
@TableField(value = "version", fill = FieldFill.INSERT)
@JsonProperty("version")
private Integer version;
/********非库表存储属性*****/
}

6
platform-common/pom.xml

@ -147,6 +147,12 @@
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>3.3.1</version> <version>3.3.1</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
</dependencies> </dependencies>

1
platform-common/src/main/java/tech/abc/platform/common/base/BaseEntity.java

@ -1,6 +1,7 @@
package tech.abc.platform.common.base; package tech.abc.platform.common.base;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;

5
platform-common/src/main/java/tech/abc/platform/common/base/BaseMapEntity.java

@ -1,6 +1,11 @@
package tech.abc.platform.common.base; package tech.abc.platform.common.base;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;

231
platform-common/src/main/java/tech/abc/platform/common/extension/EasyExcelUtils.java

@ -0,0 +1,231 @@
package tech.abc.platform.common.extension;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* EasyExcel工具类
*/
public class EasyExcelUtils {
/**
* 注入的具有排序功能的handle
*/
// private static final SortRowWriteHandler SORT_ROW_WRITE_HANDLER = new SortRowWriteHandler();
/**
* 导出excel-按指定顺序
*
* @param <T> (必须是小写并遵守阿里开发规范)
* @param list 列表数据
* @param fileName 文件名称
* @param useDefaultStyle 是否使用默认样式
* @param response 响应
*/
public static <T> Map<String, Object> exportExcelInclude(List<T> list, String fileName,Boolean useDefaultStyle, HttpServletResponse response) throws IOException {
Map<String, Object> resultMap = new HashMap<>();
if (list.size() == 0) {
resultMap.put("msg", "数据长度为空");
resultMap.put("result", -1);
return resultMap;
}
Class<?> clazz = list.get(0).getClass();
/*定义编码,格式*/
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String exportFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportFileName + ".xlsx");
response.setHeader("filename", exportFileName + ".xlsx");
response.setHeader("Access-Control-Expose-Headers", "filename");
/**
* .head(head(headNameList))
* 改行代码不可以用ExcelWriterSheetBuilder类型的变量单独写否则会包错表头长度与字段列表长度不符
*/
/*导出表格*/
ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(response.getOutputStream(), clazz)
.useDefaultStyle(useDefaultStyle)
.sheet(fileName);
excelWriterSheetBuilder.doWrite(list);
resultMap.put("msg", "excel export success");
resultMap.put("result", 0);
return resultMap;
}
/**
* 导出excel-默认顺序
*
* @param <T> (必须是小写并遵守阿里开发规范)
* @param list 列表数据
* @param fileName 文件名称
* @param useDefaultStyle 是否使用默认样式
* @param response 响应
* @param headNameList
* @param columnList 设置列字段(必须是小写)
*/
public static <T> Map<String, Object> exportExcelInclude(List<T> list, String fileName,Boolean useDefaultStyle, HttpServletResponse response, List<String> columnList, List<String> headNameList) throws IOException {
Map<String, Object> resultMap = new HashMap<>();
if (list.size() == 0) {
resultMap.put("msg", "数据长度为空");
resultMap.put("result", -1);
return resultMap;
}
if (CollectionUtils.isEmpty(headNameList)) {
/*设置表头*/
resultMap.put("msg", "表头长度为空");
resultMap.put("result", -2);
return resultMap;
}
if (CollectionUtils.isEmpty(columnList)) {
/*设置列字段*/
resultMap.put("msg", "列字段长度为空");
resultMap.put("result", -3);
return resultMap;
}
Class<?> clazz = list.get(0).getClass();
/*定义编码,格式*/
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String exportFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportFileName + ".xlsx");
response.setHeader("filename", exportFileName + ".xlsx");
response.setHeader("Access-Control-Expose-Headers", "filename");
/**
* .head(head(headNameList))
* 改行代码不可以用ExcelWriterSheetBuilder类型的变量单独写否则会包错表头长度与字段列表长度不符
*/
/*导出表格*/
ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(response.getOutputStream(), clazz)
.head(head(headNameList))
/*设置列字段(会按顺序)*/
.includeColumnFiledNames(columnList)
/*注入的具有排序功能的handle*/
// .registerWriteHandler(SORT_ROW_WRITE_HANDLER)
.useDefaultStyle(useDefaultStyle)
.sheet(fileName);
excelWriterSheetBuilder.doWrite(list);
resultMap.put("msg", "excel export success");
resultMap.put("result", 0);
return resultMap;
}
/**
* 支持动态头,行列合并导出
*
* @param response web响应
* @param headList 动态头
* @param dataList 数据列表
* @param columnMergeHandler 注入列合并
* @param rowMergeHandler 注入行合并
* @throws IOException
*/
public static Map<String, Object> writeDynamicExcel(HttpServletResponse response, @NotEmpty List<List<String>> headList, @NotEmpty List<List<Object>> dataList, @NotNull ExcelColumnMergeHandler columnMergeHandler,@NotNull ExcelRowMergeHandler rowMergeHandler) throws IOException {
Map<String, Object> resultMap = new HashMap<>();
if (dataList.size() == 0) {
resultMap.put("msg", "数据长度为空");
resultMap.put("result", -1);
return resultMap;
}
if (CollectionUtils.isEmpty(headList)) {
/*设置表头*/
resultMap.put("msg", "表头长度为空");
resultMap.put("result", -2);
return resultMap;
}
if (columnMergeHandler == null || rowMergeHandler == null) {
/*设置列字段*/
resultMap.put("msg", "行列处理器为空");
resultMap.put("result", -3);
return resultMap;
}
EasyExcel.write(response.getOutputStream())
// 设置动态头
.head(headList)
.sheet("模板")
/*注入列合并*/
.registerWriteHandler(columnMergeHandler)
/*注入行合并*/
.registerWriteHandler(rowMergeHandler)
/*传需要写入的数据,类型List<List<Object>>*/
.doWrite(dataList);
resultMap.put("msg", "excel export success");
resultMap.put("result", 0);
return resultMap;
}
/**
* 支持动态头导出
*
* @param response web响应
* @param headList 动态头
* @param dataList 数据列表
* @throws IOException
*/
public static void writeDynamicExcel(HttpServletResponse response,List<List<String>> headList, List<List<Object>> dataList) throws IOException {
EasyExcel.write(response.getOutputStream())
// 设置动态头
.head(headList)
.sheet("模板")
/*传需要写入的数据,类型List<List<Object>>*/
.doWrite(dataList);
}
/**
* 设置Excel头
*
* @param headList Excel头信息
* @return
*/
public static List<List<String>> head(List<String> headList) {
List<List<String>> list = new ArrayList<>();
for (String value : headList) {
List<String> head = new ArrayList<>();
head.add(value);
list.add(head);
}
return list;
}
/**
* Excel头对应的字段转换小写
*
* @param ColumnListTemp Excel字段
* @return
*/
public static List<String> castLowerCase(List<String> ColumnListTemp) {
List<String> ColumnList = new ArrayList<>();
for (String name : ColumnListTemp) {
ColumnList.add(StrUtil.lowerFirst(name));
}
return ColumnList;
}
}

108
platform-common/src/main/java/tech/abc/platform/common/extension/ExcelColumnMergeHandler.java

@ -0,0 +1,108 @@
package tech.abc.platform.common.extension;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.Data;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.List;
/***
* 列合并处理器
*
*/
@Data
public class ExcelColumnMergeHandler implements CellWriteHandler {
/**
* 合并字段的下标如new int[]{0,1,2,3,4,10},0-4合并,10合并
*/
private int[] mergeColumnIndex;
/**
* 从第几行开始合并如果表头占两行这个数字就是2
*/
private int mergeRowIndex;
public ExcelColumnMergeHandler() {
}
public ExcelColumnMergeHandler(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
WriteCellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :
cell.getNumericCellValue();
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :
preCell.getNumericCellValue();
// 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
//
if (curData.equals(preData)) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一个单元格未被合并,则新增合并单元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
}

1
platform-common/src/main/java/tech/abc/platform/common/extension/ExcelExportExtension.java

@ -65,7 +65,6 @@ public class ExcelExportExtension<V, E> extends BaseController {
String fileName = URLEncoder.encode("导出数据.xlsx", "UTF-8"); String fileName = URLEncoder.encode("导出数据.xlsx", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName); response.setHeader("Content-disposition", "attachment;filename=" + fileName);
// excel导出处理 // excel导出处理
ExcelWriter excelWriter = EasyExcel.write(outputStream, this.getClazz()) ExcelWriter excelWriter = EasyExcel.write(outputStream, this.getClazz())
.withTemplate(inputStream).build(); .withTemplate(inputStream).build();

87
platform-common/src/main/java/tech/abc/platform/common/extension/ExcelRowMergeHandler.java

@ -0,0 +1,87 @@
package tech.abc.platform.common.extension;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 行合并处理器
*
*/
public class ExcelRowMergeHandler implements CellWriteHandler {
private static final String KEY ="%s-%s";
//所有的合并信息都存在了这个map里面
Map<String, Integer> mergeInfo = new HashMap<>();
public ExcelRowMergeHandler() {
}
public ExcelRowMergeHandler(Map<String, Integer> mergeInfo) {
this.mergeInfo = mergeInfo;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
Integer num = mergeInfo.get(String.format(KEY, curRowIndex, curColIndex));
if(null != num){
// 合并最后一行 ,列
mergeWithPrevCol(writeSheetHolder, cell, curRowIndex, curColIndex,num);
}
}
public void mergeWithPrevCol(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex, int num) {
Sheet sheet = writeSheetHolder.getSheet();
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, curColIndex, curColIndex + num);
sheet.addMergedRegion(cellRangeAddress);
}
/**
* 添加合并行
* 比如参数(3,0,2)
* 从第三行的地0列开始向右合并2格
* 这样第三行的地0列到第2列就会合并
*
* 注意
* 合并不能冲突如果合并到已经被合并的地方会报一个POI错误
* (java.lang.IllegalStateException: Cannot add merged region B3:B6 to sheet because it overlaps with an existing merged region (A6:C6).)
*
* @param curRowIndex 当前行 需要合并的哪一行(一般用数据List的index+表头的行数,表头站的行数是1就+1是2就+2)
* @param curColIndex 合并开始列从第几行开始合并
* @param num 合并列的数量从第curColIndex行开始向右合并多少格
*/
public void add (int curRowIndex, int curColIndex , int num){
mergeInfo.put(String.format(KEY, curRowIndex, curColIndex),num);
}
}
Loading…
Cancel
Save