文件模板导出(word和pdf)——使用easypoi和docx4j

代码

依赖

    <dependencies>
        <!-- easypoi -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.3.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.3.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.3.0</version>
        </dependency>
        <!-- pdf -->
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-export-fo</artifactId>
            <version>6.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
    </dependencies>

自定义注解

用于定义需要到处的实体类的属性信息

package com.zdd.export;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author zdd
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExportFiled {

    String name() default "";

    String type() default "string";

    int height() default 200;

    int width() default 500;

    String format() default "yyy-MM-dd HH:mm:ss";

    String replace() default "";

}

属性类型定义类

package com.zdd.export;

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/10 11:26
 */
public class FiledTypeConstant {

    public final static String STRING = "string";

    public final static String IMAGE = "image";

    public final static String DATE = "date";

    public final static String LIST = "list";

    public final static String IMAGE_LIST = "imageList";

    public final static String OBJECT = "object";

    public final static String MAP = "map";

}

测试实体类

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/10 10:17
 */
@Data
public class Model {

    @ExportFiled
    private String name;

    @ExportFiled(replace = "1_男,0_女")
    private Integer gender;

    @ExportFiled
    private Integer age;

    @ExportFiled(type = "image", width = 100, height = 50)
    private String imagePath;

    @ExportFiled(type = "date", format = "yyy-MM-dd HH:mm:ss")
    private LocalDateTime date;

    @ExportFiled(type = "list")
    private List<Item> list;

    @ExportFiled(type = "map")
    private Map<String, Object> imageTest;

}

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/20 11:08
 */
@Data
public class ImageTest {

    @ExportFiled
    private String name;

    @ExportFiled(type = "image")
    private String mediaPath;

}

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/18 13:50
 */
@Data
public class Item {

    @ExportFiled
    private String name;

    @ExportFiled
    private Integer age;

    @ExportFiled(type = "date", format = "yyy-MM-dd HH:mm:ss")
    private LocalDateTime date;

}

导出工具类

package com.zdd.export.util;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import com.zdd.export.ExportFiled;
import com.zdd.export.FiledTypeConstant;
import com.zdd.export.Item;
import com.zdd.export.Model;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/10 9:09
 */
@Slf4j
public class PdfUtil<T> {

    private static String separator = File.separator;//文件夹路径分格符

    public static void main(String[] args) {
        Model model = new Model();
        model.setName("zdd");
        model.setAge(111);
//        model.setImagePath("https://img-home.csdnimg.cn/images/20201124032511.png");
        model.setImagePath("http://129.168.2.117:9000/citymanage/Rec/2021/4/1/11399/IMG_20210401_081602.jpg");
        model.setDate(LocalDateTime.now());
        ArrayList<Item> items = new ArrayList<>();
        Item item = new Item();
        item.setName("ceshi");
        item.setAge(123);
        item.setDate(LocalDateTime.now());
        item.setImagePath("https://img-home.csdnimg.cn/images/20201124032511.png");
        items.add(item);
        items.add(item);
        model.setList(items);
//        ArrayList<String> list = new ArrayList<>();
//        list.add("https://img-home.csdnimg.cn/images/20201124032511.png");
//        list.add("https://img-home.csdnimg.cn/images/20201124032511.png");
//        model.setImageList(list);
//        ArrayList<ImageTest> list = new ArrayList<>();
//        list.add(new ImageTest(){{
//            setName("zdd");
//            setMediaPath("https://img-home.csdnimg.cn/images/20201124032511.png");
//        }});
//        list.add(new ImageTest(){{
//            setName("ys");
//            setMediaPath("https://img-home.csdnimg.cn/images/20201124032511.png");
//        }});
//        list.add(new ImageTest(){{
//            setName("xdf");
//            setMediaPath("https://img-home.csdnimg.cn/images/20201124032511.png");
//        }});
//        model.setImageList(list);
        HashMap<String, Object> map = new HashMap<>();
        ImageEntity imageEntity = new ImageEntity();
        imageEntity.setUrl("https://img-home.csdnimg.cn/images/20201124032511.png");
        imageEntity.setType(ImageEntity.URL);
        imageEntity.setWidth(500);
        imageEntity.setHeight(200);
        map.put("name", "zdd");
        map.put("mediaPath", imageEntity);
        model.setImageTest(map);
        PdfUtil<Model> pdfUtil = new PdfUtil<>();
        String templatePath = PdfUtil.class.getClassLoader().getResource("templates/test.docx").getPath().replaceAll("%20", " ");
        pdfUtil.exportPdf(model, templatePath, "C:\\Users\\zdd\\Desktop\\test.docx", "C:\\Users\\zdd\\Desktop\\out.pdf");
    }

    /**
     * 导出pdf到Response请求中
     * @param t
     * @param templatePath
     * @param fileName
     * @param response
     */
    public void exportPdf2Response(T t, String templatePath, String fileName, HttpServletResponse response){
        //获取临时保存文件目录
        String upfilePath = System.getProperty("java.io.tmpdir").concat("/smartcity/pdf/");
        File upfilePathFile = new File(upfilePath);
        templatePath = PdfUtil.class.getClassLoader().getResource("templates/" + templatePath).getPath().replaceAll("%20", " ");
        if (!upfilePathFile.exists()){
            upfilePathFile.mkdirs();
        }
        String pdfPathName = upfilePath.concat(fileName + ".pdf");
        String wordPathName = upfilePath.concat(fileName + ".docx");
        File outFile = new File(pdfPathName);
        exportPdf(t, templatePath, wordPathName, pdfPathName);
        try (
                // 从response对象中得到输出流,准备下载
                OutputStream myout = response.getOutputStream();
                // 读出文件到i/o流
                FileInputStream fis = new FileInputStream(outFile);
                BufferedInputStream buf = new BufferedInputStream(fis);
        ){


            // 设置response的编码方式
            fileName = fileName + "pdf";
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
            response.setContentType("application/octet-stream;charset=utf-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            byte[] b = new byte[1024];// 相当于我们的缓存
            long k = 0;// 该值用于计算当前实际下载了多少字节
            // 开始循环下载
            while (k < outFile.length()) {
                int j = buf.read(b, 0, 1024);
                k += j;
                // 将b中的数据写到客户端的内存
                myout.write(b, 0, j);
            }
            // 将写入到客户端的内存的数据,刷新到磁盘
            myout.flush();
        } catch (Exception e) {
            log.error("导出PDF异常", e);
            throw  new RuntimeException("导出PDF异常");
        }
    }

    /**
     * 导出pdf到Response请求中
     * @param t
     * @param templatePath
     * @param fileName
     * @param response
     */
    public void exportWord2Response(T t, String templatePath, String fileName, HttpServletResponse response){
        //获取临时保存文件目录
        String upfilePath = System.getProperty("java.io.tmpdir").concat("/smartcity/word/");
        File upfilePathFile = new File(upfilePath);
        templatePath = PdfUtil.class.getClassLoader().getResource("templates/" + templatePath).getPath().replaceAll("%20", " ");
        if (!upfilePathFile.exists()){
            upfilePathFile.mkdirs();
        }
        String wordPathName = upfilePath.concat(fileName + ".docx");
        File outFile = new File(wordPathName);
        exportWord(t, templatePath, wordPathName);
        try (
                // 从response对象中得到输出流,准备下载
                OutputStream myout = response.getOutputStream();
                // 读出文件到i/o流
                FileInputStream fis = new FileInputStream(outFile);
                BufferedInputStream buf = new BufferedInputStream(fis);
        ){
            // 设置response的编码方式
            fileName = fileName + ".docx";
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
            response.setContentType("application/octet-stream;charset=utf-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            byte[] b = new byte[1024];// 相当于我们的缓存
            long k = 0;// 该值用于计算当前实际下载了多少字节
            // 开始循环下载
            while (k < outFile.length()) {
                int j = buf.read(b, 0, 1024);
                k += j;
                // 将b中的数据写到客户端的内存
                myout.write(b, 0, j);
            }
            // 将写入到客户端的内存的数据,刷新到磁盘
            myout.flush();
        } catch (Exception e) {
            log.error("导出Word异常", e);
            throw  new RuntimeException("导出Word异常");
        }
    }

    /**
     * 导出word和pdf到本地
     * @param t
     * @param templatePath
     * @param wordPath
     * @param pdfPath
     */
    public void exportPdf(T t, String templatePath, String wordPath, String pdfPath){
        Map<String, Object> map = class2Map(t);
        FileOutputStream fos = null;
//        templatePath = PdfUtil.class.getClassLoader().getResource("templates/" + templatePath).getPath().replaceAll("%20", " ");
        try {
            XWPFDocument doc = WordExportUtil.exportWord07(
                    templatePath, map);
            fos = new FileOutputStream(wordPath);
            doc.write(fos);
            fos.flush();
            convertDocx2Pdf(wordPath, pdfPath);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 导出word和pdf到本地
     * @param t
     * @param templatePath
     * @param wordPath
     */
    public void exportWord(T t, String templatePath, String wordPath){
        Map<String, Object> map = class2Map(t);
        FileOutputStream fos = null;
        templatePath = PdfUtil.class.getClassLoader().getResource("templates/" + templatePath).getPath().replaceAll("%20", " ");
        try {
            XWPFDocument doc = WordExportUtil.exportWord07(
                    templatePath, map);
            fos = new FileOutputStream(wordPath);
            doc.write(fos);
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public Map<String, Object> class2Map(T t){
        HashMap<String, Object> map = new HashMap<>();
        Class<?> tClass = t.getClass();
        Field[] declaredFields = tClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            ExportFiled annotation = declaredField.getAnnotation(ExportFiled.class);
            if (annotation != null){
                String type = annotation.type();
                String key = "".equals(annotation.name()) ? declaredField.getName() : annotation.name();
                declaredField.setAccessible(true);
                try {
                    String value = declaredField.get(t) == null ? "" : declaredField.get(t).toString();
                    switch (type){
                        case FiledTypeConstant.IMAGE:
                            if (!"".equals(value)){
                                ImageEntity image = new ImageEntity();
                                image.setHeight(annotation.height());
                                image.setWidth(annotation.width());
                                image.setUrl(value);
                                image.setType(ImageEntity.URL);
                                map.put(key, image);
                            }else {
                                map.put(key, "");
                            }
                            break;
                        case FiledTypeConstant.DATE:
                            LocalDateTime date = (LocalDateTime) declaredField.get(t);
                            if (date != null){
                                DateTimeFormatter dfDate = DateTimeFormatter.ofPattern(annotation.format());
                                value = dfDate.format(date);
                            }
                            map.put(key, value);
                            break;
                        case FiledTypeConstant.LIST:
                            List list = (List) declaredField.get(t);
                            ArrayList<Map<String, Object>> maps = new ArrayList<>();
                            for (Object filed : list) {
                                PdfUtil<Object> objectPdfUtil = new PdfUtil<>();
                                Map<String, Object> filedMap = objectPdfUtil.class2Map(filed);
                                maps.add(filedMap);
                            }
                            map.put(key, maps);
                            break;
                        case FiledTypeConstant.IMAGE_LIST:
                            List<String> imageList = (List<String>) declaredField.get(t);
                            ArrayList<ImageEntity> imageEntityList = new ArrayList<>();
                            for (String s : imageList) {
                                ImageEntity imageEntity = new ImageEntity();
                                imageEntity.setHeight(annotation.height());
                                imageEntity.setWidth(annotation.width());
                                imageEntity.setUrl(s);
                                imageEntity.setType(ImageEntity.URL);
                                imageEntityList.add(imageEntity);
                            }
                            map.put(key, imageEntityList);
                            break;
                        case FiledTypeConstant.OBJECT:
                            Object o = declaredField.get(t);
                            PdfUtil<Object> objectPdfUtil = new PdfUtil<>();
                            Map<String, Object> filedMap = objectPdfUtil.class2Map(o);
                            map.put(key, filedMap);
                            break;
                        case FiledTypeConstant.MAP:
                            map.put(key, declaredField.get(t));
                            break;
                        default:
                            String replace = annotation.replace();
                            if (!"".equals(replace)){
                                String[] replaceList = replace.split(",");
                                for (String s : replaceList) {
                                    String[] replaces = s.split("_");
                                    if (value.equals(replaces[0])){
                                        value = replaces[1];
                                        break;
                                    }
                                }
                            }
                            map.put(key, value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return map;
    }

    /**
     * word(docx)转pdf
     * @param wordPath  docx文件路径
     * @return  生成的pdf路径
     */
    public void convertDocx2Pdf(String wordPath, String pdfPath) {
        OutputStream os = null;
        InputStream is = null;
        try {
            is = new FileInputStream(new File(wordPath));
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
            Mapper fontMapper = new IdentityPlusMapper();
            fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
            fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
            fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
            fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
            fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
            fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
            fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
            fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
            fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
            fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
            fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
            fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
            fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));

            mlPackage.setFontMapper(fontMapper);

            //输出pdf文件路径和名称
//            String fileName = "pdfNoMark_" + System.currentTimeMillis() + ".pdf";
//            String pdfNoMarkPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;
            /**
             * windows环境
             */
            String pdfNoMarkPath = pdfPath;
            /**
             * linux环境
             */
//            String pdfNoMarkPath = "/java/word/" + separator + fileName;

            os = new FileOutputStream(pdfNoMarkPath);

            //docx4j  docx转pdf
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(mlPackage);
            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

            is.close();//关闭输入流
            os.close();//关闭输出流

        } catch (Exception e) {
            e.printStackTrace();
            try {
                if(is != null){
                    is.close();
                }
                if(os != null){
                    os.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }finally {
            File file = new File(wordPath);
            if(file!=null&&file.isFile()&&file.exists()){
                file.delete();
            }
        }
    }
}

测试word模板文件

在这里插入图片描述

导出效果

导出word
在这里插入图片描述
导出pdf
在这里插入图片描述

模板语法

可以参考easypoi的官方文档《模板 指令介绍》

自定义注解的使用

@ExportFiled注解是使用在类属性上的,有以下几个属性

  • name:属性的名字,会决定传入模板map中的key,默认是属性名;
  • type:属性的类型,目前有三种类型,string、image和date,string就不介绍了(默认除了image和date就是string类型),image代表图片,如何属性的类型是image,那么此字段必须传图片的url。date代表日期,默认是使用的LocalDateTime,需要配合format使用;
  • height:图片的高度,默认为200;
  • width:图片的宽度,默认为500;
  • format:日期的格式,默认格式为yyy-MM-dd HH:mm:ss;
  • replace:值得替换,以"source_target,source_target"的形式替换。

注意事项

在通过easypoi导出word模板和通过docx4j将导出的word转换成pdf的过程中会出现很多问题,下面将介绍比较重要的几个注意事项。

  • 遍历指令的使用

假设有如下的指令,其中一行遍历写在表格中,另一行遍历写在表格外
在这里插入图片描述
导出的结果如下,会发现只有表格内的指令生效了
在这里插入图片描述
因为easypoi本身是用来导出excel表格的,所以遍历的指令是没有兼容word模板的

  • 表格中的遍历指令

假如有如下模板
在这里插入图片描述
导出的word结果如下
在这里插入图片描述
可以发现表格最后一列应有的数据不见了,而且可以推测数据是被覆盖而不是没有插入。

但是如果在遍历指令的下一行表格中插入数据
在这里插入图片描述
导出的表格中是存在插入的数据的
在这里插入图片描述
可以得出结论表格中如果出现遍历数据,那么同一行的其他数据会被覆盖(包括被空白覆盖)。而且还有如下的情况出现,如果遍历的指令没有写在第一列也是无法生效的。
在这里插入图片描述
在这里插入图片描述

  • 图片的使用

如果想要在word中插入图片,需要将图片封装成一个ImageEntity对象。需要注意的是如果使用的easypoi是4.2.0及以下的版本,那么easypoi只能接口单个图片对象或者一个list集合对象包含的一系列图片,不能将图片包含在map集合中。因为easypoi在处理map集合中只会单纯将其中的value转化成string对象,并没有考虑其他类型的对象。

假设有如下的测试对象,其中的list会被解析成list包含的map对象,其中就有图片对象
在这里插入图片描述

在这里插入图片描述
下面是导出的模板
在这里插入图片描述
导出的结果,可以发现图片并没有展现
在这里插入图片描述

通过debug可以看到图片对象确实已经注入到map中
在这里插入图片描述
这个问题已经在4.3.0版本中解决了,还是同样的模板和代码,导出的结果如下
在这里插入图片描述

  • 图片错误的url

我们导出word的时候会遇到一个问题,那就是导出过程突然变慢,然后出现如下的错误,虽然最终还是可以将word导出,但是这样还是会影响使用。这个现象出现的原因就是图片的url地址有问题,然后easypoi去请求访问时连接时间会变长并超时,所以这里建议使用的图片地址一定要是正确并且能够快速访问的。
在这里插入图片描述
为了避免这种不友好的错误和过长时间的导出过程,我们可以借助下面这个工具类先将图片的url检测一遍再进行封装。

import java.net.URL;
import java.net.URLConnection;

/**
 * @description:
 * @author: zdd
 * @time: 2021/5/24 11:28
 */
public class UrlUtil {

    public static Boolean testUrlWithTimeOut(String urlString,int timeOutMillSeconds){
        URL url;
        try {
            url = new URL(urlString);
            URLConnection co =  url.openConnection();
            co.setConnectTimeout(timeOutMillSeconds);
            co.connect();
            return true;
        } catch (Exception e1) {
            return false;
        }
    }

}
  • 图片的大小

仔细观察下面的图片,第一张图是word导出,第二张图是pdf导出。可以很轻易发现第一张图片的大小比例不相同,其实不光是第一张,后面两张图片的大小也有细微的不同。
在这里插入图片描述
在这里插入图片描述
通过docx4j转换而成的pdf中的图片必定会还原成原图的长宽比例,但是图片的大小比例还是会按照设置的长宽中最大的来生成。

  • 模板的读取路径

还需要注意的是如果项目是打成jar包放在windows或者linux系统中执行的,那么模板的路径就和直接在idea中的不一致。可能存在以下的空指针异常,这是因为easypoi读取我们提供的路径发现并没有模板文件。
在这里插入图片描述
解决的办法有很多,这里提供的解决思路是通过文件流的方式读取模板文件,然后将文件copy到jar包外的指定路径中,最后使用copy出来的文件路径。

下面是转换路径的方法

    public static String convertTemplatePath(String path){
        FileOutputStream fileOutputStream = null;
        // 将模版文件写入到tomcat临时目录
        String folder = System.getProperty("catalina.home");
        File tempFile = new File(folder + File.separator + path);
        // 文件存在时不再写入
        if (tempFile.exists()) {
            return tempFile.getPath();
        }
        File parentFile = tempFile.getParentFile();
        // 判断父文件夹是否存在
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        InputStream in = PdfUtil.class.getResourceAsStream(path);
        try {
            fileOutputStream = new FileOutputStream(tempFile);
            byte[] buffer = new byte[10240];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return tempFile.getPath();
    }

其中参数是文件在jar包中的绝对路径,”/“代表的就是下面所示的路径
在这里插入图片描述
下面这个模板文件的绝对路径就是"/templates/recDetailsTemp.docx"
在这里插入图片描述

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Docx4j是一个用于处理Word文档的Java库,它提供了丰富的功能,包括创建、修改和转换Word文档等。要将Word文档转换为PDF,可以使用Docx4j提供的功能。 首先,你需要在项目中引入Docx4j库的依赖。你可以在Maven或Gradle中添加以下依赖: Maven: ```xml <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j</artifactId> <version>8.2.9</version> </dependency> ``` Gradle: ```groovy implementation 'org.docx4j:docx4j:8.2.9' ``` 接下来,你可以使用以下代码将Word文档转换为PDF: ```java import org.docx4j.Docx4J; import org.docx4j.convert.out.FOSettings; public class WordToPdfConverter { public static void main(String[] args) throws Exception { // 加载Word文档 String inputFilePath = "path/to/input.docx"; org.docx4j.openpackaging.packages.WordprocessingMLPackage wordMLPackage = Docx4J.load(new java.io.File(inputFilePath)); // 创建FOSettings对象,并设置输出格式为PDF FOSettings foSettings = Docx4J.createFOSettings(); foSettings.setWmlPackage(wordMLPackage); foSettings.setApacheFopMime("application/pdf"); // 设置输出路径 String outputFilePath = "path/to/output.pdf"; java.io.OutputStream outputStream = new java.io.FileOutputStream(outputFilePath); // 执行转换 Docx4J.toFO(foSettings, outputStream, Docx4J.FLAG_EXPORT_PREFER_XSL); // 关闭输出流 outputStream.close(); System.out.println("Word文档转换为PDF成功!"); } } ``` 以上代码中,你需要将`inputFilePath`替换为要转换的Word文档的路径,将`outputFilePath`替换为要保存的PDF文件的路径。执行代码后,将会生成对应的PDF文件。 希望以上信息对你有所帮助!如果你有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值