使用docx4j實現docx轉pdf(解決linux環境下中文亂碼問題)


1.在pom.xml中添加docx4j相關依賴

  <dependency>
			<groupId>org.docx4j</groupId>
			<artifactId>docx4j-JAXB-Internal</artifactId>
			<version>8.3.1</version>
		</dependency>
		<dependency>
			<groupId>org.docx4j</groupId>
			<artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
			<version>8.3.1</version>
		</dependency>
		<dependency>
			<groupId>org.docx4j</groupId>
			<artifactId>docx4j-export-fo</artifactId>
			<version>8.3.1</version>
		</dependency>

2.新增WordUtils工具類

import lombok.extern.slf4j.Slf4j;
import org.docx4j.Docx4J;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
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.UUID;
@Slf4j
public class WordUtils {
 
    public static void main(String[] args) throws Exception {
        WordUtils.convertDocxToPdf("D:/test/test.docx","D:/test/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();
        //加載字體文件(解決linux環境下無中文字體問題)
        if(PhysicalFonts.get("SimSun") == null) {
        	System.out.println("加載本地SimSun字體庫");
//        	PhysicalFonts.addPhysicalFonts("SimSun", WordUtils.class.getResource("/fonts/SIMSUN.TTC"));
        }
		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("FangSong"));
		fontMapper.put("幼圓", PhysicalFonts.get("YouYuan"));
		fontMapper.put("華文宋體", PhysicalFonts.get("STSong"));
		fontMapper.put("華文中宋", PhysicalFonts.get("STZhongsong"));
		fontMapper.put("等線", PhysicalFonts.get("SimSun"));
		fontMapper.put("等線 Light", PhysicalFonts.get("SimSun"));
		fontMapper.put("華文琥珀", PhysicalFonts.get("STHupo"));
		fontMapper.put("華文隸書", PhysicalFonts.get("STLiti"));
		fontMapper.put("華文新魏", PhysicalFonts.get("STXinwei"));
		fontMapper.put("華文彩雲", PhysicalFonts.get("STCaiyun"));
		fontMapper.put("方正姚體", PhysicalFonts.get("FZYaoti"));
		fontMapper.put("方正舒體", PhysicalFonts.get("FZShuTi"));
		fontMapper.put("華文細黑", PhysicalFonts.get("STXihei"));
		fontMapper.put("宋體擴展", PhysicalFonts.get("simsun-extB"));
		fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
		fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
		//解決宋體(正文)和宋體(標題)的亂碼問題
		PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
        PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
        //宋體&新宋體
  		PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
  		fontMapper.put("SimSun", simsunFont);
		//設置字體
		mlPackage.setFontMapper(fontMapper);
    }
    
}

3.在linux環境中安裝windows字體

(1)在linux(CentOS7)環境中新建文件夾/usr/share/fonts/win_font

(2)將C:\Windows\Fonts(win10)中的字體文件拷貝到/usr/share/fonts/win_font文件夾中

(3)加載字體文件

mkfontscale       //字體擴展
mkfontdir           //新增字體目錄
fc-cache -fv      //刷新緩存

(4)查看字體安裝情況

fc-list :lang=zh

4.打包部署並啟動程序即可查看最終效果,親測通過,希望對你有所幫助。

如有疑問,可留言給我,看到后會回復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM