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();
    }
相关推荐
rannn_1115 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
IKUN家族7 小时前
Spring IoC&DI
java·spring·rpc
山荷枝8 小时前
03-框架--Spring
java·后端·spring
ChaHae-In9 小时前
SpringBoot统一功能处理
java·spring boot·后端
coder!mq9 小时前
说几个常见的语法糖?
java·开发语言·算法
gugucoding9 小时前
38. 【Java】Stream API(下):高级操作与性能
java·开发语言
心平气和量大福大10 小时前
android-实例-蒲公英-更新与安装-5-签名与生成APK
android·java·开发语言
9523610 小时前
Spring-cloud配置中心
java·spring·spring cloud·微服务
ydd10010010 小时前
寻找两个正序数组的中位数 Java 题解,二分分割详解
java·开发语言
真上帝的左手12 小时前
10. 软件设计&架构-Spring Security 7 整合CAS SSO 单点登录
java·spring·架构·sso