利用docx4j word转pdf

2 篇文章 0 订阅
2 篇文章 0 订阅

依赖:

<docx4j.version>6.1.1</docx4j.version>
<export.fo.version>8.1.1</export.fo.version>

  <!--word 转 pdf -->
<dependency>
   <groupId>org.docx4j</groupId>
   <artifactId>docx4j</artifactId>
   <version>${docx4j.version}</version>
</dependency>
<dependency>
   <groupId>org.docx4j</groupId>
   <artifactId>docx4j-export-fo</artifactId>
   <version>${export.fo.version}</version>
</dependency>

工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.docx4j.Docx4J;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.org.apache.poi.util.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class WordUtils {

    public static void main(String[] args) throws Exception {
        WordUtils.convertDocxToPdf("D:/test.docx","D:/test.pdf");
    }

    /**
     * docx文档转换为PDF
     * @param body 文档
     * @param response 响应给前端
     * @return pdf 输出流
     * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
     */
    public static void convertDocxToPdf(byte[] body , HttpServletResponse response) throws Exception {
        response.setContentType("application/pdf");
        File docxFile = FileUtil.byteToFile(body, UUID.randomUUID().toString() + ".docx");
        try {
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docxFile);
            setFontMapper(mlPackage);
            Docx4J.toPDF(mlPackage, response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
            log.error("docx文档转换为PDF失败");
        }
       FileUtil.deleteTempFile(docxFile);
    }



    /**
     * docx文档转换为PDF
     *
     * @param pdfPath PDF文档存储路径
     * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
     */
    public static void convertDocxToPdf(String docxPath, String pdfPath) throws Exception {

        FileOutputStream fileOutputStream = null;
        try {
            File file = new File(docxPath);
            fileOutputStream = new FileOutputStream(new File(pdfPath));
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);
            setFontMapper(mlPackage);
            Docx4J.toPDF(mlPackage, new FileOutputStream(new File(pdfPath)));
        }catch (Exception e){
            e.printStackTrace();
            log.error("docx文档转换为PDF失败");
        }finally {
            IOUtils.closeQuietly(fileOutputStream);
        }
    }

    private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {
        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);
    }
}

太多的word转pdf搜索出来的资料,版本号不是太旧,就是太繁琐,或者仅支持window,折腾了两天,最后还好找对了资料:https://blog.csdn.net/Jason_996/article/details/81707485

感谢这位博主。虽然版本有点旧,但我整了一下,发现居然只用了两个依赖就能实现了。注:数学部分特殊字符无法正常转换

相关工具类:

import java.util.Arrays;

public class CalculateUtil {


   public static Integer add(Integer... integers){
       return Arrays.stream(integers).filter(integer -> integer!=null).reduce(0, (a, b) -> a + b);
   }

    public static void main(String[] args) {
        Integer integer = new Integer(1);
        Integer first = null;
        Integer add = add(integer, first);
        System.out.println(add);
    }

}

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lombok.extern.slf4j.Slf4j;


@Slf4j
public final class FileUtil {

	public static final String XLSX_SUFFIX = ".xlsx";

	private FileUtil() {
	}

	/**
	 * 文件转比特流
	 */
	public static byte[] fileToByte(String filePath) {
		File file = new File(filePath);
		return FileUtil.fileToByte(file);
	}

	/**
	 * 文件转比特流
	 */
	public static byte[] fileToByte(File file) {
		byte[] buffer = null;
		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			byte[] b = new byte[1024];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer;
	}

	/**
	 * 比特流转文件
	 */
	public static File byteToFile(byte[] buf, String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {

			file = new File(fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(buf);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return file;
	}

	/**
	 * 删除临时文件
	 */
	public static void deleteTempFile(File file) {
		if (file == null) {
			return;
		}
		boolean delete = file.delete();
		if (!delete) {
			log.error("删除临时文件失败");
		}
	}

	/**
	 * 返回带点的后缀
	 * 
	 * @param ext
	 * @return
	 */
	public static String getExt(String ext) {
		return ext.indexOf(".") == -1 ? "." + ext : ext;
	}

	/**
	 * 返回一个临时文件名不带后缀
	 * 
	 * @return
	 */
	public static String createTempFileName() {
		String folder = System.getProperty("java.io.tmpdir");
		String filename = folder + UUID.randomUUID();
		return filename;
	}

	/**
	 * 截取文件的后缀名 无后缀返回“”
	 * 
	 * @param fileName
	 * @return
	 */
	public static String cutFileName(String fileName) {
		String ext = StringUtil.cutName(fileName, ".");
		return ext == null ? "" : ext;
	}

	/**
	 * 生成一个临时文件
	 */
	public static File tempFile(String suffix) {
		String folder = System.getProperty("java.io.tmpdir");
		String fileName = System.currentTimeMillis() + suffix;
		String s = folder + fileName;
		return new File(s);
	}

	/**
	 * 生成临时文件和file文件名字一样的
	 */
	public static File tempFile(File file) {
		String folder = System.getProperty("java.io.tmpdir");
		String s = folder + file.getName();
		return new File(s);
	}

	/**
	 * 创建一个临时目录 + 文件名字符串
	 */
	public static String getTempFileName(String fileName) {
		String folder = System.getProperty("java.io.tmpdir");
		return folder + "/" + fileName;

	}

	/**
	 * 同名文件命名, 例如 1. a.pdf --> a(1).pdf 2. a --> a(1) 3. a(1).pdf --> a(2).pdf
	 * 4. a(1) --> a(2)
	 * 
	 * @param fileName
	 * @return
	 */
	public static String renameSameFileName(String fileName) {
		String newFileName = null;
		int i = fileName.lastIndexOf(".");
		if (i != -1) { // 有同名文件,有.作为后缀
			String rule = "(.*)\\.(.*)";
			Matcher matcher = Pattern.compile(rule).matcher(fileName);

			if (matcher.find()) {
				String fileNameNoSuffix = matcher.group(1); // 文件名
				String suffix = matcher.group(2);
				String rule2 = "(.*)\\((\\d)\\)";
				Matcher matcher1 = Pattern.compile(rule2).matcher(fileNameNoSuffix);
				if (matcher1.find()) {// 同名的文件名是 文件名(1).pdf 这种
					String number = matcher1.group(2);
					Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);
					newFileName = fileNameNoSuffix.replaceAll(rule2, "$1").concat("(" + newNumber + ").")
							.concat(suffix);
				} else { // 同名的文件名是 文件名.pdf这种 直接添加 (1).pdf
					newFileName = fileName.replaceAll(rule, "$1(1).$2");
				}
			}
		} else {// 有同名文件,没有以.作为后缀
			String rule2 = "(.*)\\((\\d)\\)";
			Matcher matcher1 = Pattern.compile(rule2).matcher(fileName);
			if (matcher1.find()) {// 同名的文件名是 文件名(1) 这种
				String number = matcher1.group(2);
				Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);
				newFileName = fileName.replaceAll(rule2, "$1").concat("(" + newNumber + ")");
			} else {
				newFileName = fileName.concat("(1)");
			}
		}
		return newFileName;
	}

	/**
	 * 截取 /sdfs/sdfsdf.pdf 中的sdfsdf.pdf
	 * 
	 * @param filePath
	 * @return
	 */
	public static String getFileNameByPath(String filePath) {
		String rule = "(.*/)(.*)";
		String fileName = filePath.replaceAll(rule, "$2");
		return fileName;
	}
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class StringUtil extends StringUtils {

    /**
     * 转换为下划线
     *
     * @param camelCaseName
     * @return
     */
    public static String underscoreName(String camelCaseName) {
        StringBuilder result = new StringBuilder();
        if (camelCaseName != null && camelCaseName.length() > 0) {
            result.append(camelCaseName.substring(0, 1).toLowerCase());
            for (int i = 1; i < camelCaseName.length(); i++) {
                char ch = camelCaseName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    result.append("_");
                    result.append(Character.toLowerCase(ch));
                } else {
                    result.append(ch);
                }
            }
        }
        return result.toString();
    }

    /**
     * 转换为驼峰
     *
     * @param underscoreName
     * @return
     */
    public static String camelCaseName(String underscoreName) {
        StringBuilder result = new StringBuilder();
        if (underscoreName != null && underscoreName.length() > 0) {
            boolean flag = false;
            for (int i = 0; i < underscoreName.length(); i++) {
                char ch = underscoreName.charAt(i);
                if ("_".charAt(0) == ch) {
                    flag = true;
                } else {
                    if (flag) {
                        result.append(Character.toUpperCase(ch));
                        flag = false;
                    } else {
                        result.append(ch);
                    }
                }
            }
        }
        return result.toString();
    }


    /**
     * 截取文件后缀
     */
    public static String cutName(String fileName,String cutString){
        int i = fileName.lastIndexOf(cutString);
        if (i==-1) {
            return null;
        }else{
            return fileName.substring(i + 1);
        }
    }

    /**
     * 劈开某个字符串得到list
     */
    public static List<String> splitString(String source,String str){
        List<String> list = new ArrayList<>();
        String[] split = source.split(str);
        Collections.addAll(list,split);
        return list;
    }


    /**
     * 去除正则的特殊符号 ( )
     */
    public static String removeRegex(String source){
        return source.replaceAll("\\(|\\)", "");
    }

    /**
     * 去除空白符 再去除 正则特殊符号
     */
    public static String removeBlankAndRegex(String source){
        return removeRegex(removeBlank(source));
    }

    /**
     * 去除空白符
     */
    public static String removeBlank(String source){
        return source.replaceAll("\\s", "");
    }

    /**
     * 正则匹配
     * @param source
     * @param rule
     * @return
     */
    public static Matcher match(String source,String rule){
        Pattern compile = Pattern.compile(rule);
        Matcher matcher = compile.matcher(source);
        if (matcher.find()) {
            return matcher;
        }
        return null;
    }


    public static String mybitsIds(List<Integer> list, String splits){
        String join = org.apache.commons.lang3.StringUtils.join(list, splits);
        return addAfterAndBefore("(", join, ")");
    }

    /**
     * 在string的前后添加字符
     * @param after
     * @param source
     * @param before
     * @return
     */
    public static String addAfterAndBefore(String after,String source,String before){
        StringBuilder stringBuilder = new StringBuilder(after);
        return stringBuilder.append(source).append(before).toString();
    }

    /**
     * 两个字符串中间添加字符串
     * @param header
     * @param tail
     * @param middle
     * @return
     */
    public static String addMiddle(String header,String tail,String... middle){
        StringBuilder stringBuilder = new StringBuilder(header);
        for (String s : middle) {
            stringBuilder.append(s);
        }
        return stringBuilder.append(tail).toString();
    }


    /**
     * 拼接带有参数的url,url后面有?拼接成 &xxx=xxx,没有?拼接?
     * @param url
     * @param param
     * @return
     */
    public static String concatUrl(String url,String... param){
        StringBuilder stringBuilder = new StringBuilder(url);
        String join = String.join("&", param);
        if (url.indexOf("?")!=-1) {
            return stringBuilder.append("&").append(join).toString();
        }else {
            StringBuilder append = stringBuilder.append("?");
            return append.append(join).toString();
        }
    }

 

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文件。 希望以上信息对你有所帮助!如果你有任何其他问题,请随时提问。
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值