Java 批量导出Word模板生成ZIP文件到浏览器默认下载位置

是不是你们要找的!是不是你们要找的!是不是你们要找的!

先看效果:

1.word模板格式

2.模板位置

3.需要的依赖

java 复制代码
        <!--POI-TL实现数据导出到word模板-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0.M2</version>
        </dependency>
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.9.1</version>
        </dependency>
        <!--支持Zip-->
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.11.5</version>
        </dependency>

4.直上代码

java 复制代码
    @Override
    public Result exportReportAAndF1List(HttpServletResponse response,List<Integer> ids) throws Exception {

        List<Map<String, Object>> arrayMap = new ArrayList<>();

        for(Integer sonId:ids) {
            //导出A 单个导出
            TestRecord testRecord = testRecordMapper.selectById(sonId);
            List<VehicleParts> vehiclePartsList = vehiclePartsMapper.selectList(new LambdaQueryWrapper<VehicleParts>().eq(VehicleParts::getModelId,
                    testRecord.getModelId()));
            Map<Integer, VehicleParts> vehiclePartsMap = vehiclePartsList.stream().collect(Collectors.toMap(VehicleParts::getId, vehicleParts -> vehicleParts));
            JSONObject vehicle = new JSONObject();
            Unit unit = null;
            if (StringUtils.isNotBlank(testRecord.getVehicleInfo())) {
                vehicle = JSONObject.parseObject(testRecord.getVehicleInfo());
                Integer unitId = vehicle.getInteger("unitId");
                if (unitId != null) {
                    unit = unitMapper.selectById(unitId);
                }
            }

            // 1 设置编码格式、文件名称
            response.setCharacterEncoding("utf-8");

            Map<String, Object> map = new HashMap<>();

            // 1.基本属性填充
            map.put("fName", "F" + testRecord.getModelId());
            map.put("fileName", Optional.ofNullable(testRecord.getFileName()).orElse("--"));
            map.put("modelName", Optional.ofNullable(testRecord.getModelName()).orElse("--")); //Optional.ofNullable().orElse("--")
            map.put("powerHours", (int) Math.floor(Optional.ofNullable(vehicle.getDouble("powerHours")).orElse(0.0)));
            map.put("plateNumber", Optional.ofNullable(vehicle.get("plateNumber")).orElse("--"));
            map.put("powerPackWorkingHours", (int) Math.floor(Optional.ofNullable(vehicle.getDouble("powerPackWorkingHours")).orElse(0.0)));
            if (!unit.getParent().equals(0)) {
                Unit unitFather = unitMapper.selectById(unit.getParent());
                map.put("unitName", Optional.ofNullable(unitFather.getUnitName() + "/" + unit.getUnitName()).orElse("--"));
            } else {
                map.put("unitName", Optional.ofNullable(unit.getUnitName()).orElse("--"));
            }
            map.put("powerPackYieldHours", (int) Math.floor(Optional.ofNullable(vehicle.getDouble("powerPackYieldHours")).orElse(0.0)));
            map.put("factoryDate", Optional.ofNullable(vehicle.get("factoryDate")).orElse("--"));
            map.put("taskPayloadWorkingHours", (int) Math.floor(Optional.ofNullable(vehicle.getDouble("taskPayloadWorkingHours")).orElse(0.0)));
            map.put("mileage", (int) Math.floor(Optional.ofNullable(testRecord.getMileage()).orElse(0.0)));
            map.put("createTime", Optional.ofNullable(testRecord.getCreateTime()).orElse("--"));
            map.put("remark", Optional.ofNullable(testRecord.getRemark()).orElse("--"));

            //list所属系统

            //拼接数据结构
            // 2.商品详情列表填充
            List<Map<String, Object>> goodsWordList = new ArrayList<>();

            //下面的行数
            List<FillData> data = data(testRecord.getDetail(), vehiclePartsMap);
            for (int i = 0; i < data.size(); i++) {
                Map<String, Object> goodsMap = new HashMap<>();
                goodsMap.put("id", i + 1);
                goodsMap.put("item", Optional.ofNullable(data.get(i).getItem()).orElse("--"));
                goodsMap.put("result", Optional.ofNullable(data.get(i).getResult()).orElse("--"));
                goodsMap.put("partsName", Optional.ofNullable(data.get(i).getPartsName()).orElse("--"));
                goodsMap.put("subsystemName", Optional.ofNullable(data.get(i).getSubsystemName()).orElse("--"));
                goodsMap.put("trueOrFalse", Optional.ofNullable(data.get(i).getTrueOrFalse()).orElse("--"));
                goodsWordList.add(goodsMap);
            }
            map.put("goods", goodsWordList);

            arrayMap.add(map);
        }

        // 设置响应的内容类型
        response.setContentType("application/zip");

        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        String zipName = URLEncoder.encode("F1检测信息报表.zip", "UTF-8").replaceAll("\\+", "%20");

        response.setHeader("Content-Disposition", "attachment;filename=" + zipName);

        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())){

            for (Map<String, Object> data : arrayMap){

                //使用 ByteArrayOutputStream 来创建内存中的 Word 文件
                ByteArrayOutputStream wordOut = new ByteArrayOutputStream();

                //数据写入模板
                XWPFDocument document = new MyXWPFDocument(Objects.requireNonNull(this.getClass().getResourceAsStream("/template/testAF1.docx")));
                // 读取模板
                WordExportUtil.exportWord07(document, data);

                document.write(wordOut);

                // 添加Word文件到Zip包中
                zipOutputStream.putNextEntry(new ZipEntry(data.get("fileName") + ".docx"));
                zipOutputStream.write(wordOut.toByteArray());
                zipOutputStream.closeEntry();
            }

            zipOutputStream.finish();

        }catch (IOException e){

            e.printStackTrace();
            throw new RuntimeException("Error creating ZIP file",e);

        }

        return Result.success();
    }
相关推荐
xlsw_1 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹2 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭3 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫3 小时前
泛型(2)
java
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石3 小时前
12/21java基础
java
李小白663 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp3 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶4 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb