使用poi-tl实现图片批量导出到word模板

poi-tl工具附上:

        Poi-tl Documentation (deepoove.com)​​​​​​

引用:Maven

<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.1</version>
</dependency>

正文:

        在word模板中同时插入多张图片,我们使用的是区对块+图片标签的方式
        {{?photo}}{{@img}}{{/photo}}

格式:

{
  "photo": [
    { "img": "xxx.jpeg" },
    { "img": "aaa.jpeg" },
    { "img": "bbb.jpeg" }
  ]
}

实际代码:

public String exportDataWord(ExportWordDateDto dto, LoginVo loginVo) {
    //1.1 查出模板   伪代码
    Document formWordTemplate = xxxserviceImpl.getDataTempale();
    //1.2 查出数据  键值对   伪代码
    Document document = xxxserviceImpl.getData();
    String url = null;

    //2.读出模板,这里的模板是一个url,可以跟换成本地地址
    if (ObjectUtil.isEmpty(formWordTemplate)) {
        return "没有找到导出word数据模板!";
    }
    if (ObjectUtil.isEmpty(document)) {
        return "当前表单没有数据,请先新增数据后在进行导出!";
    }
    //宽
    Integer imagesWide = formWordTemplate.getInteger("images_wide");
    //高
    Integer imagesHigh = formWordTemplate.getInteger("images_high");
    InputStream inputStream = null;
    ByteArrayInputStream byteArrayInputStream = null;
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        //请求模板文件
        URL wordUrl = new URL(formWordTemplate.getString("word_url"));
        HttpURLConnection conn = (HttpURLConnection) wordUrl.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        //得到输入流
        inputStream = conn.getInputStream();

        //图片字段  因为图片要做特殊处理,所以在设计模板的时候就把图片字段给提前拿出来了 这里就比如图片字段是 img
        String[] imagesFields = formWordTemplate.getString("images_fields").split(",");
        if (ObjectUtil.isNotEmpty(imagesFields)) {
            List<String> imagesFieldList = Arrays.asList(imagesFields);
            ArrayList<String> keyList = new ArrayList<>(document.keySet());
            // 创建渲染数据
            for (String key : keyList) {
                //区块对list
                List<Map<String, PictureRenderData>> list = new ArrayList<>();
                if (imagesFieldList.contains(key)) {
                    Object o = document.get(key);
                    URL imageUrl = null;
                    //判断是否是list对象
                    if (o instanceof List) {
                        List<Document> documents = (List<Document>) o;
                        //这里采用得是poi-tl得区块对方式实现得
                        for (Document value : documents) {
                            //区块对list属性值
                            Map<String, PictureRenderData> map = new HashMap<>();
                            imageUrl = new URL(value.getString("url"));
                            HttpURLConnection urlConnection = (HttpURLConnection) imageUrl.openConnection();
                            if (200 == urlConnection.getResponseCode()) {
                                InputStream is = urlConnection.getInputStream();
                                //PictureType.suggestFileType(value.getString("url"))根据连接获取后缀名  一定要指定类型,不然图片数据展示出不来
                                map.put(key, Pictures.ofStream(is, PictureType.suggestFileType(value.getString("url"))).size(imagesWide, imagesHigh).create());
                                list.add(map);
                            }
                        }
                    } else {
                        imageUrl = new URL(document.getString(key));
                        HttpURLConnection urlConnection = (HttpURLConnection) imageUrl.openConnection();
                        if (200 == urlConnection.getResponseCode()) {
                            InputStream is = urlConnection.getInputStream();
                            document.put(key, Pictures.ofStream(is, PictureType.suggestFileType(document.getString(key))).size(imagesWide, imagesHigh).create());
                        }
                    }
                    //封装区对块得list外层对象   这里的phto就是word模板的图片的区对块标签
                    document.put("photo", list);
                    document.remove(key);
                }
            }
        }
        byteArrayInputStream = new ByteArrayInputStream(out.toByteArray());
        XWPFTemplate template = XWPFTemplate.compile(inputStream).render(document);

        template.write(outputStream);

//上传文件流伪代码
        url = uploadFile(outputStream);
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseVo.fail2("服务异常,导出失败!");
    } finally {
        try {
            if (ObjectUtil.isNotEmpty(inputStream)) {
                inputStream.close(); // 关闭输入流
            }
            if (ObjectUtil.isNotEmpty(byteArrayInputStream)) {
                byteArrayInputStream.close();
            }
            out.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //3.返回结果
    return url;
}

运行结果:

        模板:

         实际内容:      

上面代码涉及到一些伪代码,根据自己的业务进行相应的修改就可以了,返回值建议返回对象。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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文档,其中包含合并列的表格。 请确保按照您的需求修改代码,并根据模板文件的位置进行相应的调整。 希望对您有所帮助!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值