Java使用poi-tl动态生成word和pdf

Java使用poi-tl动态生成word和pdf

lixiangrong
2024-01-25 / 0 评论 / 36 阅读 / 正在检测是否收录...

1.导入依赖,注意版本必须匹配

详情参见官网 poi-tl官方文档

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!--导出word-->
<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.10.5</version>
</dependency>
<!--xpwf转pdf(根据word导出pdf)-->
<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>
    <version>2.0.2</version>
</dependency>
<!--SpringEL表达式-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>5.3.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.draco1023/poi-tl-ext -->
<!--富文本解析-->
<dependency>
    <groupId>io.github.draco1023</groupId>
    <artifactId>poi-tl-ext</artifactId>
    <version>0.3.22</version>
    <exclusions>
        <exclusion>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.准备文件模板

{{data.id}}
{{data.sno}}
{{data.name}}
{{data.sex}}
{{data.age}}
{{data.createTime}}
图片解析
{{@data.img}}
富文本
{{data.content}}
SpringEL表达式对时间格式化
{{data.createTime == null ? "" : new java.text.SimpleDateFormat('yyyy-MM-dd').format(data.createTime)}}
字符串集合遍历
{{?data.list}}
{{=#this}}
{{/data.list}}
复杂对象集合遍历和取值
{{?data.cityList}}
{{id}}
{{name}}
{{/data.cityList}}

Test
Test

3.生成文件到本地

@Test
public void test()
{
    Student entity = new Student();
    entity.setId("1");
    entity.setSno("1");
    entity.setName("张三");
    entity.setSex("男");
    entity.setAge(25);
    entity.setCreateTime(new Date());
    final ArrayList<String> strings = new ArrayList<>();
    strings.add("str1");
    strings.add("str2");
    strings.add("str3");
    entity.setList(strings);
    // Base64图片
    String base64Str = "这里填写Base64编码的图片字符串,此处限于篇幅省略";
    entity.setImg(Pictures.ofBase64(base64Str, PictureType.JPEG).size(96, 45).create());
    // 网络图片
    // entity.setImg("https://www.lxrao.com/myfile/cat.jpg");
    // 富文本
    entity.setContent("此处粘贴富文本,此处限于篇幅省略");
    List<City> list = new ArrayList<>();
    City city1 = new City();
    city1.setId(1);
    city1.setName("BeiJing"+"\n");
    list.add(city1);
    City city2 = new City();
    city2.setId(1);
    city2.setName("ShangHai");
    list.add(city2);
    entity.setCityList(list);
    try(InputStream inputStream = getClass().getResourceAsStream("/templates/test.docx"))
    {
        Assert.isTrue(Objects.nonNull(inputStream),"模板不存在!");
        HashMap<String,Object> map = new HashMap<>();
        map.put("data",entity);
        // 富文本解析
        HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();
        Configure configure = Configure.builder().bind("data.content", htmlRenderPolicy).useSpringEL().build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream,configure).render(map);
        // 1.导出word文件
        template.writeAndClose(new FileOutputStream("C:\\Users\\LiXiangrong\\Desktop\\test.docx"));
        // 2.导出pdf文件
        PdfOptions options = PdfOptions.create();
        FileOutputStream outPDF = new FileOutputStream("C:\\Users\\LiXiangrong\\Desktop\\test.pdf");
        PdfConverter.getInstance().convert(template.getXWPFDocument(), outPDF, options);
        outPDF.close();
    } catch (IOException e)
    {
        System.out.println(e.getMessage());
    }
}

4.下载到web端

package com.example.springbootdemo.utils;

import com.deepoove.poi.XWPFTemplate;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Objects;

public class ExportUtil
{
    private static final String WORD = ".docx";

    private static final String PDF = ".pdf";

    private static final String TYPE = "application/octet-stream";
    
    public static void exportWordOrPDF(HttpServletResponse response,Object o,String tempName,String exportName,String fileType)
    {
        final String fileSuffix = "word".equals(fileType) ? WORD : PDF;
        // 赋值数据对象
        HashMap<String,Object> map = new HashMap<>();
        map.put("data",o);
        // 读取模板文件
        InputStream inputStream = ExportUtil.class.getResourceAsStream("/templates/"+tempName);
        Assert.isTrue(Objects.nonNull(inputStream),"模板文件不存在!");
        XWPFTemplate template = XWPFTemplate.compile(inputStream).render(map);
        // 生成文件
        response.setContentType(TYPE);
        try {
            response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(exportName+fileSuffix, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try
        {
            OutputStream outputStream = response.getOutputStream();
            if ("word".equals(fileType))
            {
                template.writeAndClose(outputStream);
            } else
            {
                PdfOptions options = PdfOptions.create();
                PdfConverter.getInstance().convert(template.getXWPFDocument(), outputStream, options);
                outputStream.close();
            }
        } catch (IOException e)
        {
            throw new RuntimeException("导出异常!");
        }
    }
    
}

5.控制层接口

@GetMapping("/exportPDF")
    public void exportPDF(HttpServletResponse response)
    {
        Student entity = new Student();
        entity.setId("1");
        entity.setSno("1");
        entity.setName("张三");
        entity.setSex("男");
        entity.setAge(25);
        ExportUtil.exportWordOrPDF(response,entity,"test.docx","导出pdf测试","pdf");
    }

    @GetMapping("/exportWORD")
    public void exportWORD(HttpServletResponse response)
    {
        Student entity = new Student();
        entity.setId("1");
        entity.setSno("1");
        entity.setName("张三");
        entity.setSex("男");
        entity.setAge(25);
        ExportUtil.exportWordOrPDF(response,entity,"test.docx","导出word测试","word");
    }

6.浏览器地址栏输入url测试

Test

7.前端下载方法

<el-button type="primary" @click="downloadToWord" :loading="downloadLoading">下载</el-button>

下载公共方法写在工具类中

// Blob下载文件
export function downloadFileByBlob (content, filename) {
    let eleLink = document.createElement("a");
    eleLink.download = filename;
    eleLink.style.display = "none";
    let blob = new Blob([content]);
    eleLink.href = URL.createObjectURL(blob);
    document.body.appendChild(eleLink);
    eleLink.click();
    document.body.removeChild(eleLink);
}

下载方法放在methods:{}中

import { downloadFileByBlob } from '@/utils'

// Loading
downloadLoading: false,
downloadToWord() {
  const { id } = this.topicsInfo
  this.downloadLoading = true
  request({
    url: `/api/szyd/JTopicRequestMeeting/export`,
    method: 'get',
    responseType: "blob",
    data: {
       id,
       type: 'word', 
       temp: this.curTemp,
       exportName: 'test'
    }
  }).then(file => {
    this.$message({ message: '文件下载成功', type: 'success' })
    downloadFileByBlob(file, document.title + '.docx')
  }).finally(() => {
    this.downloadLoading = false
  })
},
0

评论 (0)

取消