CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

Java文件处理系列之:word转pdf-永久免费的源码丞旭猿

日常操作中,word转pdf是较为常见的操作。尤其是前端上传word文档,需要在页面预览文档的情况。前端直接预览word需要特殊的处理,但是如果由后端先把word转为pdf,再预览,就会比较简单。

效果预览:

原始word文件.docx

转换之后的pdf文件.pdf

接下来就分享实测过的实现方式。

环境:JDK11、Springboot 2.3.7.RELEASE、windows10、Maven

  1. 第一步,Maven 依赖配置,主要导入一些工具包
<dependencies><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-testartifactId><scope>testscope>dependency><dependency><groupId>org.projectlombokgroupId><artifactId>lombokartifactId><optional>trueoptional>dependency><dependency><groupId>org.apache.commonsgroupId><artifactId>commons-lang3artifactId><version>3.4version>dependency><dependency><groupId>com.deepoovegroupId><artifactId>poi-tlartifactId><version>1.10.2version>dependency><dependency><groupId>fr.opensagres.xdocreportgroupId><artifactId>fr.opensagres.poi.xwpf.converter.pdfartifactId><version>2.0.2version>dependency><dependency><groupId>org.apache.poigroupId><artifactId>poi-scratchpadartifactId><version>4.1.2version>dependency><dependency><groupId>fr.opensagres.xdocreportgroupId><artifactId>fr.opensagres.poi.xwpf.converter.coreartifactId><version>2.0.2version>dependency><dependency><groupId>fr.opensagres.xdocreportgroupId><artifactId>fr.opensagres.poi.xwpf.converter.xhtmlartifactId><version>2.0.2version>dependency><dependency><groupId>com.itextpdfgroupId><artifactId>itextpdfartifactId><version>5.5.13.2version>dependency><dependency><groupId>com.itextpdf.toolgroupId><artifactId>xmlworkerartifactId><version>5.5.13.2version>dependency><dependency><groupId>com.itextpdfgroupId><artifactId>itext-asianartifactId><version>5.2.0version>dependency><dependency><groupId>com.itextpdfgroupId><artifactId>html2pdfartifactId><version>4.0.1version>dependency><dependency><groupId>org.jsoupgroupId><artifactId>jsoupartifactId><version>1.14.3version>dependency>dependencies>
  1. 第二步,service 业务层构造
packagecom.yalin.cn.fileutil.word.service;importjava.io.InputStream;importjava.io.OutputStream;/**
 *@description: word生成pdf
 *@author: lyl
 *@create: 2021-05-08 16:31:47
 **/publicinterfaceIWordConvertPdfService{/**
     * docx 转pdf
     *
     *@paramsourcePath word路径
     *@paramtargetPath pdf路径
     *@paramimageDir   word中的图片临时存放路径
     *@returnboolean
     */booleanconvert(String sourcePath, String targetPath, String imageDir);/**
     * docx 转pdf
     *
     *@paramin         word文件流
     *@paramtargetPath pdf路径
     *@paramimageDir   word中的图片临时存放路径
     *@returnboolean
     */booleanconvert(InputStream in, String targetPath, String imageDir);/**
     * docx 转pdf
     *
     *@paramin       word文件流
     *@paramout      pdf文件流
     *@paramimageDir word中的图片临时存放路径
     *@returnboolean
     *@throwsException 抛出异常
     */booleanconvert(InputStream in, OutputStream out, String imageDir)throwsException;
}
  1. 第三步,service impl 业务实现层构造
packagecom.yalin.cn.fileutil.word.service.impl;importcom.yalin.cn.fileutil.util.OfficeUtil;importcom.yalin.cn.fileutil.word.service.IWordConvertPdfService;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Service;importjava.io.InputStream;importjava.io.OutputStream;importjava.nio.file.Files;importjava.nio.file.Paths;importjava.util.Objects;/**
 *@description: word生成pdf
 *@author: lyl
 *@create: 2021-05-08 16:31:47
 **/@Service@Slf4jpublicclassWordConvertPdfServiceImplimplementsIWordConvertPdfService{/**
     * docx 转pdf
     *
     *@paramsourcePath word路径
     *@paramtargetPath pdf路径
     *@paramimageDir   word中的图片临时存放路径
     *@returnboolean
     */@Overridepublicboolean convert(String sourcePath, String targetPath, String imageDir) {try(InputStream inputStream = Files.newInputStream(Paths.get(sourcePath));
             OutputStream outputStream = Files.newOutputStream(Paths.get(targetPath))) {returnconvert(inputStream, outputStream, imageDir);
        }catch(Exception e) {
            log.error("convert(String, String, String)异常:{}", e);
        }returnfalse;
    }/**
     * docx 转pdf
     *
     *@paramin         word文件流
     *@paramtargetPath pdf路径
     *@paramimageDir   word中的图片临时存放路径
     *@returnboolean
     */@Overridepublicboolean convert(InputStreamin, String targetPath, String imageDir) {try(OutputStream outputStream = Files.newOutputStream(Paths.get(targetPath))) {returnconvert(in, outputStream, imageDir);
        }catch(Exception e) {
            log.error("convert(String, String, String)异常:{}", e);
        }returnfalse;
    }/**
     * docx 转pdf
     *
     *@paramin       word文件流
     *@paramout      pdf文件流
     *@paramimageDir word中的图片临时存放路径
     *@returnboolean
     */@Overridepublicboolean convert(InputStreamin, OutputStreamout, String imageDir) throws Exception {if(Objects.isNull(in)) {thrownew Exception("模板文件流为null!");
        }if(Objects.isNull(out)) {thrownew Exception("目标文件流为null!");
        }try{// word转pdfOfficeUtil.docxConvertPdf(in,out, imageDir);returntrue;
        }catch(Exception e) {
            log.error("fill(InputStream, OutputStream, String)异常:{}", e);
        }returnfalse;
    }
}
  1. 第四步,真正实现转换的工具类
package com.yalin.cn.fileutil.util;importcom.itextpdf.text.*;importcom.itextpdf.text.pdf.BaseFont;importcom.itextpdf.text.pdf.PdfWriter;importcom.itextpdf.tool.xml.XMLWorkerHelper;importcom.yalin.cn.fileutil.font.AutoFontFactory;importfr.opensagres.poi.xwpf.converter.core.BasicURIResolver;importfr.opensagres.poi.xwpf.converter.core.FileImageExtractor;importfr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;importfr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;importorg.apache.commons.lang3.StringUtils;importorg.apache.poi.xwpf.usermodel.XWPFDocument;importorg.jsoup.Jsoup;importorg.jsoup.nodes.Element;importorg.jsoup.nodes.Entities;importorg.jsoup.select.Elements;importjava.io.*;importjava.nio.charset.Charset;importjava.util.Objects;/**
 * @description: word 转pdf
 * @author: lyl
 * @create: 2021-04-23 11:09:51
 **/publicclassOfficeUtil {/**
     * 将docx格式文件转成html
     *
     * @param in       docx文件流
     * @param imageDir docx文件中图片存储目录
     * @return html
     */publicstaticStringdocx2Html(InputStreamin,StringimageDir) throws Exception {Stringcontent =null;
        ByteArrayOutputStream baos =null;try{// 1> 加载文档到XWPFDocumentXWPFDocumentdocument=newXWPFDocument(in);// 2> 解析XHTML配置(这里设置IURIResolver来设置图片存放的目录)XHTMLOptions options = XHTMLOptions.create();// 存放word中图片的目录if(Objects.nonNull(imageDir)) {
                options.setExtractor(newFileImageExtractor(newFile(imageDir)));
                options.URIResolver(newBasicURIResolver(imageDir));
                options.setIgnoreStylesIfUnused(false);
                options.setFragment(true);
            }// 3> 将XWPFDocument转换成XHTMLbaos =newByteArrayOutputStream();
            XHTMLConverter.getInstance().convert(document, baos, options);
        }catch(Exception e) {
            e.printStackTrace();thrownewException(e);
        }finally{try{if(in!=null) {in.close();
                }if(baos !=null) {
                    content =newString(baos.toByteArray(),"utf-8");
                    baos.close();
                }
            }catch(Exception e) {
                e.printStackTrace();
            }
        }returncontent;
    }/**
     * 使用jsoup规范化html
     *
     * @param html html内容
     * @return 规范化后的html
     */privatestaticStringformatHtml(Stringhtml) {
        org.jsoup.nodes.Document doc = Jsoup.parse(html);// 去除过大的宽度Stringstyle = doc.attr("style");if(StringUtils.isNotEmpty(style) && style.contains("width")) {
            doc.attr("style","");
        }
        Elements divs = doc.select("div");for(Element div : divs) {StringdivStyle = div.attr("style");if(StringUtils.isNotEmpty(divStyle) && divStyle.contains("width")) {
                div.attr("style","");
            }
        }// jsoup生成闭合标签doc.outputSettings().syntax(org.jsoup.nodes.Document.OutputSettings.Syntax.xml);
        doc.outputSettings().escapeMode(Entities.EscapeMode.xhtml);returndoc.html();
    }/**
     * html转成pdf
     *
     * @param html html
     * @param out  输出pdf文件流
     */publicstaticvoidhtmlToPdf(Stringhtml, OutputStream out) throws Exception {
        Documentdocument=null;
        ByteArrayInputStream bais =null;try{// 纸document=newDocument(PageSize.A4);// 笔PdfWriter writer = PdfWriter.getInstance(document, out);document.open();// html转pdfbais =newByteArrayInputStream(html.getBytes("UTF-8"));
            XMLWorkerHelper.getInstance().parseXHtml(writer,document, bais,
                    Charset.forName("UTF-8"),newFontProvider() {@OverridepublicbooleanisRegistered(Strings) {returnfalse;
                        }@OverridepublicFont getFont(Strings,Strings1,booleanembedded, float size, int style, BaseColor baseColor) {// 配置字体Font font =null;try{
                                BaseFont bf = AutoFontFactory.getBaseFont();
                                font =newFont(bf, size, style, baseColor);
                                font.setColor(baseColor);
                            }catch(Exception e) {
                                e.printStackTrace();
                            }returnfont;
                        }
                    });
        }catch(Exception e) {
            e.printStackTrace();thrownewException(e);
        }finally{if(document!=null) {document.close();
            }if(bais !=null) {try{
                    bais.close();
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }/**
     * docx 转pdf
     *
     * @param in       docx文件流
     * @param out      pdf文件流
     * @param imageDir docx中图片存放路径
     * @return boolean
     */publicstaticbooleandocxConvertPdf(InputStreamin, OutputStream out,StringimageDir) {try{StringdocxHtml = docx2Html(in, imageDir);
            docxHtml = formatHtml(docxHtml);
            htmlToPdf(docxHtml, out);returntrue;
        }catch(Exception e) {
            e.printStackTrace();
        }returnfalse;
    }
}

备注:OfficeUtil中的AutoFontFactory属于自定义的字体。因为linux环境下不支持某些中文字体,导致乱码。解决方案之一,就是从windows字体库中复制一个,放到resource目录下,在代码中引用即可。

packagecom.yalin.cn.fileutil.font;importcom.itextpdf.text.DocumentException;importcom.itextpdf.text.pdf.BaseFont;importjava.io.IOException;/**
 *@description: 字体工厂
 *@author: lyl
 *@create: 2022-01-17 15:38:29
 **/publicclassAutoFontFactory{/**
     * 获取基础字体
     *
     *@returnBaseFont
     *@throwsIOException
     *@throwsDocumentException
     */publicstaticBaseFontgetBaseFont()throwsIOException, DocumentException{// 方案一:使用资源字体(需要有字体)BaseFont bf = BaseFont.createFont("/font/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 方案二:使用本地字体(本地需要有字体)// BaseFont bf = BaseFont.createFont("C:/Windows/Fonts/seguisym.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 方案二:使用jar包:iTextAsian,这样只需一个jar包就可以了// BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);returnbf;
    }
}

测试类

@TestvoidwordConvertPdf() {StringbasePath ="C:\\Users\\lyl\\Desktop\\";StringsourcePath = basePath +"原始word文件.docx";StringtargetPath = basePath +"转换之后的pdf文件.pdf";StringimagePath = basePath +"img"+ File.separator;
        WordConvertPdfServiceImpl tt =newWordConvertPdfServiceImpl();booleanflag = tt.convert(sourcePath, targetPath, imagePath);
        System.out.println(flag);
    }

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容