利用POI,根据word模板生成对应的数据并导出下载-源码

 提供核心的俩个方法,写代码的一般看了就懂。 附件生成问题不一定要使用代码里的工具,什么都可以。


/**
 * @Author LS
 * @Description //TODO emc12
 * @Date 14:42 2022/9/14 0014
 * @Param [filePath, systemFlag, taskIds, sampliId]
 *  @Param 
 * @return java.util.Map<java.lang.String,java.lang.Object>
 **/
    @Override
    public Map<String,Object> createReport(String filePath, String systemFlag, List<String> taskIds, String sampliId) {
        String filePathLocal = "";
        String minioReportPath = "";
        String reportPath = "";
        Map<String,Object> reMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(filePath)) {
                System.out.println("File Path is null");
                return reMap;
            }
            //模板数据组装
            Map<String, Object> data = new HashMap<>();
            //获取所有的标签
            InputStream infile = new URL(filePath).openStream();
            //获取所有的标签
            List<MetaTemplate> elementTemplates = XWPFTemplate.compile(infile).getElementTemplates();
            infile.close();
            //List<MetaTemplate> elementTemplates = XWPFTemplate.compile(filePath).getElementTemplates();
            List<String> tableMapKey = new ArrayList<>();
            String plable = "";//如果有上级 这就是上级的标签
            for (MetaTemplate elementTemplate : elementTemplates) {
                String templateName = elementTemplate.toString();
                log.info("===================come in =======createReport==============templateName = : " + templateName);
                String structure = ""; // 层级结构
                Map<String, Object> blockListMap = new HashMap<>();
                // 进入组装数据
                packageData(elementTemplate, blockListMap, data, tableMapKey, taskIds, sampliId, structure);
            }

            LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
            //LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(true);
            //LoopRowTableRenderPolicy hackLoopSameLineTableRenderPolicy = new LoopRowTableRenderPolicy(true);
            Configure config = null;
            if (!CollectionUtils.isEmpty(tableMapKey)) {
                ConfigureBuilder bind = Configure.builder();
                for (int i = 0; i < tableMapKey.size(); i++) {
                    bind.bind(tableMapKey.get(i), policy);
                }
                config = bind.build();
            }


            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //sdf.format(new Date());
            filePathLocal = filePathTemp +  sdf.format(new Date());
            File file = new File(filePathLocal);
            if(!file.exists()){
                file.mkdirs();
            }
            long tms = System.currentTimeMillis();
            String fileName =  tms + ".docx";
            //filePathLocal = System.getProperty("user.dir") + "/"+ ff +"_"+ System.currentTimeMillis() + ".docx";
            filePathLocal += "/"+ fileName;
            log.info("filePathLocal: " + filePathLocal);
            InputStream infile1 = new URL(filePath).openStream();
            if (null != config) {
                //获取所有的标签
                XWPFTemplate template = XWPFTemplate.compile(infile1, config).render(data);
                //template.writeToFile("D:\\Users\\emc12\\Desktop\\自动化对接资料\\circle.docx");
                template.writeToFile(filePathLocal);
                log.info("writeToFile = : " + filePathLocal);
            } else {
                XWPFTemplate template = XWPFTemplate.compile(infile1).render(data);
                //template.writeToFile("D:\\Users\\emc12\\Desktop\\自动化对接资料\\circle.docx");
                template.writeToFile(filePathLocal);
                log.info("writeToFile = : " + filePathLocal);
            }
            log.info("因为地址做了映射 导致最终生成的和实际的地址不一样。");
            minioReportPath = minioPath+sdf.format(new Date()) + "/"+ fileName;
            log.info("out file path = : " + minioReportPath);
            /*File filePt = new File(filePathLocal);
            //File filePtLo = new File(filePathLocal);
            if(!filePt.exists()){
                log.info("filePt file is not exists." + filePt);
                reMap.put("attachR","");
                return reMap;
            }
            FileInputStream fileInputStream = null;
            ByteArrayOutputStream byteArrayOutputStream = null;
            try {
                fileInputStream = new FileInputStream(filePt);
                byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] b = new byte[1024];
                int n;
                while ((n = fileInputStream.read(b)) != -1) {
                    byteArrayOutputStream.write(b, 0 , n);
                }
                AttachDto attachDto = new AttachDto();
                attachDto.setFileBytes(byteArrayOutputStream.toByteArray());
                attachDto.setOriginalName(fileName);
                R<Attach> attachR = attachClient.putFileAttach(attachDto);
                reMap.put("attachR",attachR);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fileInputStream != null) {
                        fileInputStream.close();
                    }
                    if (byteArrayOutputStream != null) {
                        byteArrayOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }*/
            //minioReportPath = "D:/Users/emc12/Desktop/bladexdoc/123.pdf";
            MinIOUtils.builder().endpoint(endpoint).accessKey(accessKey).secretKey(secretKey).bucketName(bucketName).build();
            MinIOUtils.putObject(bucketName, fileName, filePathLocal);
            String fileReportPath = MinIOUtils.getPresignedUrl(bucketName, fileName, 7);
            log.info("report filr path = : " + fileReportPath);
            reMap.put("bucketName",bucketName);
            reMap.put("fileName",fileName);
            reMap.put("filePath",fileReportPath);
            infile1.close();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            return reMap;
        } catch (IOException | ServerException | InsufficientDataException | ErrorResponseException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) {
            log.error(e.toString());
            return reMap;
        }
        return reMap;
    }
 


/**
 * @return void
 * @Author LS
 * @Description 根据模板组装数据
 * @Date 19:19 2022/6/23 0023
 * @Param [elementTemplate, structure, data, plable, tableMapKey, taskId]
 * 模板标签,层级,数据,标签,表名,任务ID
 **/
public void packageData(MetaTemplate elementTemplate,
                        Map<String, Object> blockListMap,
                        Map<String, Object> data,
                        List<String> tableMapKey,
                        List<String> taskIds, String sampliId, String structure) {
    //标签段落
    if (elementTemplate instanceof RunTemplate) {
        String tagName = ((RunTemplate) elementTemplate).getTagName();
        // 组装表格数据时需要的key
        if (tagName.indexOf("_tables") >= 0) {
            String tableKey = ((RunTemplate) elementTemplate).getTagName();
            tagName = tagName.replace("_tables", "");
            String labId ="";
            List<LimsReportTemplateLabel> templateLabels = limsReportTemplateLabelService.queeryByPidLname(null, tagName, null);
            if (!CollectionUtils.isEmpty(templateLabels)) {
                for (LimsReportTemplateLabel lab : templateLabels) {
                    LimsReportTemplateLabel reportTemplateLabel = limsReportTemplateLabelService.queryById(lab.getParentId().toString());
                    if (reportTemplateLabel.getLabelCode().equals(structure)) {
                        labId = lab.getId().toString();
                        break;
                    }
                }
                //查询 标签对应的数据
                List<LimsReportTemplateData> templateData = limsReportTemplateDataService.queryDataByLabelIdList(labId, taskIds, sampliId);
                if (!CollectionUtils.isEmpty(templateData)) {
                    List<Map<String, Object>> tableList = new ArrayList<>();
                    Map<String, List<JSONObject>> stringListMap = toGroup(JSONObject.toJSONString(templateData));
                    Map<String, List<Map<String, Object>>> result = new HashMap<>();
                    for (Map.Entry<String, List<JSONObject>> entry : stringListMap.entrySet()) {
                        List<JSONObject> value = entry.getValue();
                        log.info("entry.getKey():{}" , entry.getKey());
                        result.put(entry.getKey(), toList(value));
                    }
                    log.info("result = : " + JSONObject.toJSONString(result));
                    for (String key : result.keySet()) {
                        List<Map<String, Object>> maps = result.get(key);
                        for (int i = 0; i < maps.size(); i++) {
                            Map<String, Object> stringObjectMap = maps.get(i);
                            tableList.add(stringObjectMap);
                        }
                    }
                    if (StringUtils.isNotEmpty(structure) && !CollectionUtils.isEmpty(blockListMap)) {
                        blockListMap.put(tableKey,tableList);
                        data.put(structure,blockListMap);
                    } else if(CollectionUtils.isEmpty(blockListMap) && StringUtils.isNotEmpty(structure)) {
                        blockListMap.put(tableKey,tableList);
                        data.put(structure,blockListMap);
                    } else {
                        data.put(structure,blockListMap);
                    }

                    //格式表格时需要用到  这里记录有多少个表格
                    tableMapKey.add(tableKey);
                }
            }
        }
    }
    //进入区块内容区
    if (elementTemplate instanceof BlockTemplate) {
        String tagName = ((BlockTemplate) elementTemplate).getStartMark().getTagName(); // 标签名称
        log.info("tagname = " + tagName);
        //根據模板裡面的區塊標籤查 標籤數據
        List<LimsReportTemplateLabel> templateLabels = limsReportTemplateLabelService.queeryByPidLname(null, tagName, null);
        if (!CollectionUtils.isEmpty(templateLabels)) {
            String lableId = templateLabels.get(0).getId().toString(); //标签ID
            String pid = templateLabels.get(0).getParentId().toString();//标签父ID
            //根据任务ID和标签ID 查该标签下的所有子标签对应的数据
            List<LimsReportTemplateData> templateData = limsReportTemplateDataService.queryDataByLabelIdList(lableId, taskIds, sampliId);
            if (!CollectionUtils.isEmpty(templateData)) {
                Map<String, List<JSONObject>> stringListMap = toGroup(JSONObject.toJSONString(templateData));
                Map<String, List<Map<String, Object>>> result = new HashMap<>();
                for (Map.Entry<String, List<JSONObject>> entry : stringListMap.entrySet()) {
                    List<JSONObject> value = entry.getValue();
                    result.put(entry.getKey(), toList(value));
                }
                log.info("所有子标签对应的数据 = " + JSONObject.toJSONString(result));
                Map<String, Object> limitData = new HashMap<>();
                //多条数据循环组装
                for (String key : result.keySet()) {
                    List<Map<String, Object>> maps = result.get(key);
                    for (int i = 0; i < maps.size(); i++) {
                        Map<String, Object> stringObjectMap = maps.get(i);// 单条数据
                        String labelType = stringObjectMap.get("labelType").toString(); // 每条数据的类型
                        for (String keyCode : stringObjectMap.keySet()) {
                            //组装单条数据
                            if (!"labelType".equals(keyCode)) {
                                if (ReportCommon.LABLE_TYPE_IMAGE.equals(labelType)) {
                                    log.info("keyCode = : {};    imagePath = : {}",keyCode,stringObjectMap.get(keyCode).toString());
                                    try {
                                        //limitData.put(keyCode, Pictures.ofLocal(stringObjectMap.get(keyCode).toString()).altMeta("No Image!").create());
                                        String pictures = stringObjectMap.get(keyCode).toString();
                                        if(StringUtils.isNotEmpty(pictures)){
                                            if(pictures.contains("[")){
                                                pictures = pictures.replace("[","");
                                            }
                                            if(pictures.contains("]")){
                                                pictures = pictures.replace("]","");
                                            }
                                            String[] split = pictures.split(",");
                                            String pic = split[0];
                                            // 网络图片(注意网络耗时对系统可能的性能影响)
                                            limitData.put(keyCode, Pictures.ofUrl(pic).size(100, 100).create());
                                        }
                                    } catch (Exception e) {
                                        limitData.put(keyCode, stringObjectMap.get(keyCode).toString());
                                    }
                                } else if (ReportCommon.LABLE_TYPE_GRAPH.equals(labelType)) {
                                    //先调用echar组件生成echars图,然后获取图片地址 当作图片展示
                                    JSONObject jobj = (JSONObject) stringObjectMap.get(keyCode);
                                    log.info("============jobj= " + jobj);
                                    String imgPath = echarsAssembleNew(jobj, taskIds, sampliId,filePathTemp);
                                    log.info("============imgPath= " + imgPath);
                                    try{
                                        limitData.put(keyCode, Pictures.ofBase64(imgPath, PictureType.PNG).altMeta("No Image!").create());
                                        //limitData.put(keyCode, Pictures.ofLocal(imgPath).altMeta("No Image!").create());
                                    } catch (Exception e) {
                                        limitData.put(keyCode, stringObjectMap.get(keyCode).toString());
                                    }
                                } else {
                                    limitData.put(keyCode, stringObjectMap.get(keyCode));
                                }
                            }
                        }
                    }
                }
                if (StringUtils.isNotEmpty(structure)){
                    blockListMap.put(tagName,limitData);
                    data.put(structure,blockListMap);
                } else {
                    structure = tagName ;
                    for (String key : limitData.keySet()) {
                        blockListMap.put(key,limitData.get(key));
                    }
                    data.put(tagName,blockListMap);
                }
            } else {
                structure = tagName ;
            }
        }
        List<MetaTemplate> templates = ((BlockTemplate) elementTemplate).getTemplates();
        while (templates.iterator().hasNext()) {
            packageData(templates.iterator().next(), blockListMap, data, tableMapKey, taskIds, sampliId, structure);
            templates.remove(templates.iterator().next());
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中使用poi-tl库来导出带有合并列的Word表格并下载,您可以按照以下步骤操作: 1. 首先,确保您的Spring Boot项目中已经添加了poi-tl的依赖。您可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.6.0</version> </dependency> ``` 2. 创建一个Controller来处理导出请求。例如,创建一个名为WordExportController的类,并添加一个处理导出请求的方法。 ```java import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.*; import com.deepoove.poi.util.BytePictureUtils; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Controller public class WordExportController { @GetMapping("/export") public ResponseEntity<InputStreamResource> exportWord() throws IOException { // 创建一个数据模型 List<List<String>> tableData = new ArrayList<>(); tableData.add(createRow("Merged Cells", "Cell 3")); tableData.add(createRow("Cell 4", "Cell 6")); // 使用poi-tl的XWPFTemplate生成Word文档 XWPFTemplate template = XWPFTemplate.compile("templates/template.docx").render( new DataTable(tableData) .setHeader(createRow("Header 1", "Header 2")) .setCellWidth(2000) // 设置单元格宽度 .setHeaderCellStyle(new CellStyle().setBold(true).setColor("FFFFFF").setBgColor("336699")) .setOddRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("99CCFF")) .setEvenRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("CCEEFF")) ); // 将生成Word文档转换为字节数组 ByteArrayOutputStream out = new ByteArrayOutputStream(); template.write(out); byte[] documentBytes = out.toByteArray(); // 设置下载响应的头信息 HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment", "merged_table.docx"); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 创建一个包含Word文档字节数组的InputStreamResource InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(documentBytes)); // 返回响应实体 return ResponseEntity.ok() .headers(headers) .body(resource); } private List<String> createRow(String cell1, String cell2) { List<String> row = new ArrayList<>(); row.add(cell1); row.add(cell2); return row; } } ``` 3. 在resources目录下创建一个名为template.docx的Word模板文件。在模板文件中,您可以根据自己的需求设置表格样式和内容。 4. 启动您的Spring Boot应用程序,并访问导出请求的URL(例如:http://localhost:8080/export)。将会自动下载名为merged_table.docx的Word文档,其中包含合并列的表格。 请确保按照您的需求修改代码,并根据模板文件的位置进行相应的调整。 希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值