documents4j导出pdf

发布于:2025-07-01 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、前言

        上一篇我们介绍了导出word,既然有了导出word,那么到处pdf也将会出现,导出word和pdf基本上是配套的需求,跑不了,那么本次我就简单介绍一下导出pdf。

二、代码实现

        2.1、依赖引入

        导出pdf是基于documents4j实现的,需要引入一些依赖,pom文件的话大家以实际情况编写,比如小永哥本地只加了documents4j-local和documents4j-transformer-msoffice-word就好了,如果只引这两个报不全的话,建议大家讲依赖包都documents4j都加到pom文件中,除了documents4j还有一个org下的zeroturnaround依赖,详情请看下图。

        2.2、代码实现

package com.relation;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import java.io.*;
public class PdfTest {
    public static void convert(String inputPath, String outputPath) throws Exception {
        File inputFile = new File(inputPath);
        File outputFile = new File(outputPath);

        try (InputStream docx = new FileInputStream(inputFile);
             OutputStream pdf = new FileOutputStream(outputFile)) {

            IConverter converter = LocalConverter.builder().build();
            converter.convert(docx)
                    .as(DocumentType.DOCX)
                    .to(pdf)
                    .as(DocumentType.PDF)
                    .execute();
            converter.shutDown();
        }
    }

    public static void main(String[] args) {
        try {
            convert("C:\\Users\\ASP.NET\\Downloads\\导出测试文件.docx", "C:\\Users\\ASP.NET\\Downloads\\导出测试文件.pdf");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

        

        2.3、web实现

        我们通过2.2步骤可以看到,已经能实现了,我们再来看看开发过程中的写法,其实是大同小异,都是对文件流的操作而已。我们看代码。

@PostMapping("/exportPdfFile")
    public void exportPdfFile(HttpServletResponse response){

        //创建XWPFDocument
        XWPFDocument doc = getXWPFDocument();
        ServletOutputStream outputStream = null;
        try{
            //获取doc的输入流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            doc.write(baos);
            InputStream in = new ByteArrayInputStream(baos.toByteArray());
            outputStream = response.getOutputStream();
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("web测试导出.pdf", "UTF-8"));
            IConverter converter = LocalConverter.builder().build();
            converter.convert(in)
                    .as(DocumentType.DOCX)
                    .to(outputStream)
                    .as(DocumentType.PDF)
                    .execute();
            converter.shutDown();
        }catch (Exception e){
            log.error(e.getMessage(),e);
            throw new RuntimeException("导出异常");
        }finally {
            if(Objects.nonNull(outputStream)){
                try {
                    outputStream.close();
                    doc.close();
                }catch (Exception e){
                }
            }
        }
    }

    private XWPFDocument getXWPFDocument(){
        try {
            Resource resource = new ClassPathResource("model/导出模板.docx");
            XWPFDocument doc = new XWPFDocument(resource.getInputStream());
            //获取段落
            List<XWPFParagraph> paragraphs = doc.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                //从段落中获取书签
                List<CTBookmark> bookmarkStartList = paragraph.getCTP().getBookmarkStartList();
                for (CTBookmark ctBookmark : bookmarkStartList) {
                    String ctBookmarkName = ctBookmark.getName();
                    if("exportTitle".equals(ctBookmarkName)){
                        // 清除原有内容
                        paragraph.getRuns().forEach(run -> run.setText("", 0));
                        // 添加新内容
                        paragraph.createRun().setText("导出测试标题!!");
                    }
                    if("tableTitle".equals(ctBookmarkName)){
                        // 清除原有内容
                        paragraph.getRuns().forEach(run -> run.setText("", 0));
                        // 添加新内容
                        paragraph.createRun().setText("测试导出表格标题!!");
                    }
                    if("tableInfo".equals(ctBookmarkName)){
                        // 在书签位置创建表格
                        XWPFTable table = doc.insertNewTbl(paragraph.getCTP().newCursor());
                        //删除默认行
                        table.removeRow(0);
                        //插入3行
                        for (int i = 0; i < 3; i++) {
                            table.createRow();
                        }
                        List<XWPFTableRow> rows = table.getRows();
                        String[] headers = {"序号","姓名","年龄","城市"};
                        XWPFTableRow headerRow = table.getRow(0);
                        for(int i=0; i<headers.length; i++) {
                            headerRow.createCell().setText(headers[i]);
                        }
                        // 添加数据行
                        String[][] data = {{"1","小永哥","18","北京"},
                                {"2","胡彪","45","吉林"}};
                        for (int i = 0; i < data.length; i++) {
                            XWPFTableRow row = table.getRow(i+1);
                            String[] rowData = data[i];
                            for(int j=0; j<rowData.length; j++) {
                                row.createCell().setText(rowData[j]);
                            }
                        }
                    }
                }
            }
            return doc;
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return null;
        }
    }

        基于接口形式的代码我们也演示完了,基本上导出pdf的代码就到此了,核心思路其实是根据word文件生成pdf,简单来说就是word转pdf。

三、结语

        本期word转pdf看似很完美,其实还差最核心的一步,就是我们在第二章节的代码实现,目前只能运行在windows环境,如果一旦代码要部署到生产环境,那么就无法使用了,因为word转pdf需要依赖LiberOffice,Windows环境大家基本上都会安装office,所以并未感知到office的作用,而生产环境是linux的话,就需要再安装一套基于linux的LiberOffice,这个问题小永哥暂时还未解决,等解决后,小永哥会再补充一篇,本期暂时就到这里了,晚安......


网站公告

今日签到

点亮在社区的每一天
去签到