当前位置: 首页 > news >正文

做缓网站合肥市建设网

做缓网站,合肥市建设网,让别人做网站是要每年续费吗,如何去建设一个企业网站文章目录 前言一、EasyExcel二、使用步骤1.引入jar包2.数据准备2.1 数据库 3.方法实例3.1 无实体的导入3.1.1 Controller3.1.2 Service3.1.3 Listener3.1.4 Utils3.1.5 无实体导入数据返回说明 3.2 无实体的导出3.2.1 无实体导出数据(这里只贴出关键代码,Service代码处理)3.2.2…

文章目录

  • 前言
  • 一、EasyExcel
  • 二、使用步骤
    • 1.引入jar包
    • 2.数据准备
      • 2.1 数据库
    • 3.方法实例
      • 3.1 无实体的导入
        • 3.1.1 Controller
        • 3.1.2 Service
        • 3.1.3 Listener
        • 3.1.4 Utils
        • 3.1.5 无实体导入数据返回说明
      • 3.2 无实体的导出
        • 3.2.1 无实体导出数据(这里只贴出关键代码,Service代码处理)
        • 3.2.2 Controller
        • 3.2.2 无实体导出总结
      • 原创不易,望一键三连 (^ _ ^)


前言

今天产品提了个需求,导入导的Excel文件表头根据数据库的配置来。
因为之前大部分的导入和导出都是有固定表头或者固定的模板来做导入导出,这个需求。。。嗯,搞起!!!


一、EasyExcel

EasyExcel前面已经有过介绍了,这里不做具体介绍,大家看EasyExcel官网: EasyExcel官网
这里主要参考EasyExcel不创建对象的读和不创建对象的写

二、使用步骤

1.引入jar包

	<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>

2.数据准备

2.1 数据库

数据库表及数据

3.方法实例

3.1 无实体的导入

3.1.1 Controller
@RestController
@RequestMapping("/product")
@Slf4j
@Api(tags = "产品控制器")
public class ProductController {@PostMapping("/v1/importCountryGroupConf")@ApiOperation(value = "批量导入国家分组配置", httpMethod = "POST")public ResponseBean importCountryGroupConf(@RequestParam("file") MultipartFile file){try {return productService.importCountryGroupConf(file);} catch (Exception e) {log.error("国家分组配置导入报错:具体报错信息:{}",e.getMessage(),e);return ResponseBean.buildFail(50002,"导入失败!!!");}}
}
3.1.2 Service
@Slf4j
@Service
public class ProductService extends BaseService<Product> {public ResponseBean<Void> importCountryGroupConf(MultipartFile file) {// 文件解析及返回List<Map<String, String>> readResults = DynamicHeadImportUtils.importExcel(file);log.info("导入内容====>{}", JSONObject.toJSONString(readResults));// 获取所有国家分组List<CountryGroupConf> groupConfList = groupConfService.lambdaQuery().eq(CountryGroupConf::getDelFlag, DelFlagEnums.NORMAL.getCode()).list();// 将国家分组配置按照国家名称进行分组,返回的Map,key为国家名称,value为国家分组配置的idMap<String, Long> countryGroupConfMap = groupConfList.stream().collect(Collectors.toMap(CountryGroupConf::getGroupName, CountryGroupConf::getId));// 商品Code列表List<String> productCodes = new ArrayList<>();List<Product> updateCondition = new ArrayList<>();for (int i = 0; i < readResults.size(); i++) {int lineNum = i + 2;Product product = new Product();List<Long> groupConfIds = new ArrayList<>();for (Map.Entry<String, String> entry : readResults.get(i).entrySet()) {String key = entry.getKey();String value = entry.getValue();if ("SKU".equals(key)) {if (productCodes.contains(value)) {return ResponseBean.buildFail("第" + lineNum + "行,SKU:" + value + "存在重复!!!");} else {product.setProductCode(value);productCodes.add(value);}} else {if (ObjectUtil.isNotNull(countryGroupConfMap.get(key)) && StringUtils.isNotBlank(value)) {if (!"可售".equals(value)) {return ResponseBean.buildFail("第" + lineNum + "行" + key + "分组请正确填写!!!");} else {groupConfIds.add(countryGroupConfMap.get(key));}}}}if (CollectionUtil.isNotEmpty(groupConfIds)) {product.setCountryGroupConfIds(groupConfIds);updateCondition.add(product);}}// 是否有属性不为"成品"的SKUList<Product> productList = this.getDao().queryByProductCodes(productCodes);if (CollectionUtil.isEmpty(productList)) {return ResponseBean.buildFail("SKU不存在,请确认数据是否正确!!!");}List<String> filterResults = productList.stream().filter(s -> Integer.valueOf(s.getAttributeCode()) != 1).map(Product::getProductCode).distinct().collect(Collectors.toList());if (CollectionUtil.isNotEmpty(filterResults)) {return ResponseBean.buildFail("SKU:" + String.join(",", filterResults) + "属性不为成品!!!");}// 计算productCodes和filterResults的单差集List<String> queryCodes = productList.stream().map(Product::getProductCode).distinct().collect(Collectors.toList());List<String> diff = CollectionUtil.subtractToList(productCodes, queryCodes);if (CollectionUtil.isNotEmpty(diff)) {return ResponseBean.buildFail("SKU:" + String.join(",", diff) + "不存在,请确认数据是否填写正确!!!");}// productList按照productCode分组Map<String, Long> productIdMap = productList.stream().collect(Collectors.toMap(Product::getProductCode, Product::getId));// 更新产品信息updateCondition.forEach(x -> {if (ObjectUtil.isNotEmpty(productIdMap.get(x.getProductCode()))) {Date now = new Date();String nickName = BaseContextHandler.getNickName();Product product = new Product();product.setId(productIdMap.get(x.getProductCode()));product.setCountryGroupConfIds(x.getCountryGroupConfIds());product.setUpdateBy(nickName);product.setUpdateTime(now);getDao().update(product);// 日志ProductCodeLog codeLog = new ProductCodeLog();codeLog.setProductId(product.getId());codeLog.setOperateType("批量更新");codeLog.setContent("修改可售国家/地区配置");codeLog.setCreateUser(nickName);codeLog.setCreateTime(now);productCodeLogMapper.insert(codeLog);}});return ResponseBean.buildSuccess();}
}
3.1.3 Listener
/*** NoModelDataListener class.** @author zs* @program: naikai* @description: EasyExcel_不创建对象的读_监听器* @date 2024/10/21*/
@Slf4j
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {// 表头数据(存储所有的表头数据)private List<Map<Integer, String>> headList = new ArrayList<>();// 数据体private List<Map<Integer, String>> dataList = new ArrayList<>();@Override       // 这里会返回一行行的返回头public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {// 存储全部表头数据log.info("获取表头Start=====>");headList.add(headMap);log.info("=====>获取表头End");}@Override       // 处理每一行数据public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {dataList.add(data);}@Override       // 全部处理结束执行public void doAfterAllAnalysed(AnalysisContext context) {}public List<Map<Integer, String>> getHeadList() {return headList;}public List<Map<Integer, String>> getDataList() {return dataList;}}
3.1.4 Utils
/*** ExcelDynamicHeadImportUtils class.** @author zs* @program: naikai* @description: EasyExcel_动态表头导入_工具类* @date 2024/10/21*/
@Slf4j
public class DynamicHeadImportUtils {/*** 动态表头导入功能_无实体** @param file 文件* @return*/public static List<Map<String, String>> importExcel(MultipartFile file) {try {// Sept 1: 校验传入文件是否为空if (file == null) {throw new CheckException("传入数据为空");}// Sept 2: 引入监听器(此处需注意,监听器不可被Spring管理)NoModelDataListener readListener = new NoModelDataListener();// Sept 3: 开始处理excelEasyExcelFactory.read(file.getInputStream(), readListener).sheet(0).doRead();// 获取表头(判空)List<Map<Integer, String>> headList = readListener.getHeadList();if (CollectionUtil.isEmpty(headList)) {throw new CheckException("Excel表头不能为空");}// 获取表数据(判空)List<Map<Integer, String>> dataList = readListener.getDataList();if (CollectionUtil.isEmpty(dataList)) {throw new CheckException("Excel数据内容不能为空");}// 获取头部,取最后一次解析的列头数据Map<Integer, String> excelHeadIdxNameMap = headList.get(headList.size() - 1);// 封装数据体List<Map<String, String>> excelDataList = new ArrayList<>();for (Map<Integer, String> dataRow : dataList) {HashMap<String, String> rowData = new HashMap<>();excelHeadIdxNameMap.entrySet().forEach(columnHead -> {rowData.put(columnHead.getValue(), dataRow.get(columnHead.getKey()));});excelDataList.add(rowData);}return excelDataList;} catch (Exception e) {log.error("解析文件失败===>{}", e.getMessage(), e);throw new RuntimeException("导入失败=====>" + e.getMessage());}}
}
3.1.5 无实体导入数据返回说明

参考3.1.2方法中的返回类型:
导入内容

3.2 无实体的导出

3.2.1 无实体导出数据(这里只贴出关键代码,Service代码处理)
		// 可用国家分组配置(动态表头数据来源)List<CountryGroupConf> confs = groupConfService.lambdaQuery().eq(CountryGroupConf::getDelFlag, com.smallrig.middleground.common.enums.DelFlagEnums.NORMAL.getCode()).orderByAsc(CountryGroupConf::getId).list();Map<String, Long> countryGroupConfMap = confs.stream().collect(Collectors.toMap(CountryGroupConf::getGroupName, CountryGroupConf::getId));// 动态表头生成,第一列写死SKU,其他的根据查询的国家分组配置结果写入,查询结果是按照国家分组配置id排序(升序)List<List<String>> dynamicHeads = ListUtils.newArrayList();dynamicHeads.add(Arrays.asList("SKU"));confs.forEach(x -> dynamicHeads.add(Arrays.asList(x.getGroupName())));exportProduct.setCountryGroupConfDynamicHeads(dynamicHeads);//  商品的国家分组配置idsMap<String, List<Long>> groupConfMap = products.stream().filter(x -> CollectionUtil.isNotEmpty(x.getCountryGroupConfIds())).collect(Collectors.toMap(Product::getProductCode, Product::getCountryGroupConfIds));// 动态数据的写入,注意:表头和数据体的数据必须顺序一致,没有数据用null代替,否则就会出现错位问题List<List<Object>> datas = ListUtils.newArrayList();for (Map.Entry<String, List<Long>> entry : groupConfMap.entrySet()) {String productCode = entry.getKey();List<Long> confIds = entry.getValue();// 动态数据体List<Object> dataList = new ArrayList<>();// 表头第一列是SKU,所以对应数据体第一列必须是SKUdataList.add(productCode);// 根据表头的顺序,依次写入对应数据,如果商品没有表头国家配置,则置空for (int i = 1; i < dynamicHeads.size(); i++) {// 获取具体表头String head = dynamicHeads.get(i).get(0);Long id = countryGroupConfMap.get(head);// 判断商品的国家分组配置id是否包含了当前表头对应的国家分组配置id,如果有就写入可售,没有就置空if (confIds.contains(id)) {dataList.add("可售");}else {dataList.add(null);}}datas.add(dataList);}
3.2.2 Controller
@RestController
@RequestMapping("/product")
@Slf4j
@Api(tags = "产品控制器")
public class ProductController {
@PostMapping("/v1/export")public ResponseBean export(HttpServletResponse response,HttpServletRequest requests, @RequestBody ExportProductRequest request) throws Exception {try {//创建Excel文件File file = new File(path + "/" + fileName);if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}file.createNewFile();// 查询数据结果ExportProduct exportProduct = productService.exportObjectV2(conversionRequest, Long.valueOf(currentUserId));// 使用EasyExcel写入数据try (OutputStream out = new FileOutputStream(file)) {ExcelWriter excelWriter = EasyExcel.write(out).build();// 可售国家地区WriteSheet sheet11 = EasyExcel.writerSheet(10, "可售国家地区").head(exportProduct.getCountryGroupConfDynamicHeads()).build();excelWriter.write(exportProduct.getCountryGroupConfDatas(), sheet11);// 完成写入excelWriter.finish();// 修改down文件为成功downClient.updateDown(downId);log.info("成品编码异步导出=====>end");}} catch (IOException e) {log.error("成品编码异步导出异常", e);throw new RuntimeException(e);}return ResponseBean.buildSuccess();}
}
3.2.2 无实体导出总结

无实体导出关键在于表头和数据体的数据必须顺序一致,没有数据用null代替,否则就会出现错位问题

原创不易,望一键三连 (^ _ ^)

http://www.yayakq.cn/news/307724/

相关文章:

  • 柳州网站建设价格梅州市建设局网站
  • 阿里云企业网站备案海口建站模板系统
  • 一个dede管理两个网站建设部网站 防火规范
  • 万网主机 建网站怎么制作表格教程
  • 网站建设视频教程淮安做网站的公司有哪些公司
  • 桂林医院网站建设网站建设中源码编程同样重要
  • 福永网站建设多少钱网页制作平台是什么
  • 能自己做谱子的网站手机端网站开发建设内容
  • 免费申请注册网站青岛建手机网站哪家好
  • 网站的登录功能一般是用cookie做的广州app开发平台
  • 网站模板下载之后怎么做做推广的网站带宽需要多少钱
  • 2_网站建设的一般步骤包含哪些网站自动识别移动终端
  • 网站做seo推广百度知道提问
  • 如东网站开发网站建设选择题
  • 西安大型网站建设公司排名杭州保洁公司保洁服务
  • 济南百度整站seo推广舟山市住房和城乡建设局网站
  • 做特殊原产地证的网站北京海淀的保险公司
  • 域名连接到网站wordpress 导入 附件
  • 南京凯盛建设集团官方网站asp网站密码
  • 广州第一网站上海公共招聘网怎么打不开
  • 网站制作有前途吗wordpress自建页面
  • seo推广网站郑州网络安全科技馆
  • 网站开发 php手表网欧米茄
  • 手机网站域名和pc域名的区别如何做淘宝客自己的网站
  • 网站建设找盖亚科技关键词资源
  • 苏州高级网站建设全国住房和城乡建设部网站
  • 高端广告公司网站建设价格wordpress yii
  • 网站ip指向列表网站界面的版式架构
  • 合肥网站设计哪家公司好网页中的基本元素有哪些
  • 手机网站 uiseo网站优化培训价格