Html转Word和Pdf实践总结(一)

3,886 阅读3分钟

这是我的第一篇掘金博客,开启掘金写作之路。

年前老板专门找我说,来!帮忙整个小demo,将html页面导出来,要两个类型,一个是word(文字版),另一个是pdf(图片版)。

(哎!又是帮忙,上次就是帮了个忙,结果到最后都得是我一个人弄!)
哎,好的!(还是只能欣然答应)
下面就是入坑的开始。
首先将html转成word,我百度了好多种方法,有通过poi实现的,还有spire.doc、aspose等等
那我就一个一个试吧
由于他们需要加上固定的页眉和页脚。我就心想先用poi的模板做吧。
我还省点事(#^.^#)

word模板.png

public void exportWord(HttpServletResponse response, String htmlUrl) {
    String htmlContent = null;
    try {
        htmlContent = readUrl(htmlUrl);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //获取html内 需要的内容
    HashMap hashMap = getHtmlContent(htmlContent);
    String title = "";
    if (hashMap.size() != 0) {
        title = hashMap.get("doctitle").toString();
        Pattern p = Pattern.compile("\s*|\t|\r|\n");
        Matcher m = p.matcher(title);
        title = m.replaceAll("");
        System.out.println("获取--" + title);
    }
    try {
        //word模板文件流 这种方法不会在linux上或者jar启动失效
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("static" + File.separator + "template" + File.separator + "mb.docx");
        // hashMap -- 对应模板中的id,组成的map,作用是用value替换key值
        XWPFTemplate template = XWPFTemplate.compile(inputStream).render(hashMap);
        //生成文件名
        String fileName = ".docx";//文件名 带后缀
        // 设置强制下载不打开
        response.setContentType("application/msword");
        // 设置文件名,解决中文乱码问题
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-Disposition",
                "attachment; filename="" + URLEncoder.encode(title, "UTF-8") + fileName + """);
        OutputStream out = response.getOutputStream();
        template.write(out);
        out.flush();
        out.close();
        template.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

搞定收工!^_^
然而结局并不完美

poi导出word.png
虽然看似完美,页眉页脚,文字都在。但是样式都没啦 (ΩДΩ))
这时我才意识到。这里只是文本的替换,并不带样式。不过我心想,本就是让我做个小demo,起个头,样式的话,就让那边开始改改应该就没问题了。那就先过叭。╮(╯▽╰)╭
接下来就是pdf了
我想反正word整出来了,直接从word转pdf不就完了,页眉页脚啥也不用管。多nice!
查了之后发现aspose就可以。好的!开始干!查找代码!粘贴!好!不出意外的话,应该是要出意外了!
没错,报错了!jar包有问题,然后就开始漫长的找jar旅途。发现这个好多都是csdn上的下载,又都需要积分或者你是“尊贵的vip用户”然鹅我并不是!┭┮﹏┭┮ 没钱连代码也写不好,一jar难求啊。不过好在经过不懈的努力,终于找到了一个19.2版本的(想要jar包的可以自行到结尾拿取),那就试试吧。导入!等待自动引入。。。成功!nice!接下来就是修改其中参数合并我的代码

public static void doc2pdfOut(InputStream inputStream, OutputStream outputStream) {
    try {
        long start = System.currentTimeMillis();
        Document doc = new Document(inputStream);
        System.out.println("创建Document");
        doc.save(outputStream, SaveFormat.PDF);
        System.out.println("====PDF转化Stream==== 用时:" + (System.currentTimeMillis() - start) + "毫秒");
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("==PDF转换出异常==");
    }
}
public void exportPdf(HttpServletResponse response, String htmlUrl) {
    String htmlContent = null;
    try {
        htmlContent = readUrl(htmlUrl);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //获取html内 需要的内容
    HashMap hashMap = getHtmlContent(htmlContent);
    ByteArrayOutputStream baos = null;
    try {
        //word模板文件流 这种方法不会在linux上或者jar启动失效
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("static" + File.separator + "template" + File.separator + "mb.docx");
        String title = hashMap.get("doctitle").toString();
        System.out.println("title = " + title);
        Pattern p = Pattern.compile("\s*|\t|\r|\n");
        Matcher m = p.matcher(title);
        title = m.replaceAll("");
        XWPFTemplate template = XWPFTemplate.compile(inputStream).render(hashMap);
        baos = new ByteArrayOutputStream();
        template.write(baos);
        FileUtils fileUtils = new FileUtils();
        response.setContentType("application/force-download");
        // 设置文件名,解决中文乱码问题
        String fileName = ".pdf";//文件名 带后缀
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-Disposition",
                "attachment; filename="" + URLEncoder.encode(title, "UTF-8") + fileName + """);
        long start = System.currentTimeMillis();
        System.out.println("输出pdf====");
        fileUtils.doc2pdfOut(new ByteArrayInputStream(baos.toByteArray()), response.getOutputStream());
        System.out.println("耗时====" + (System.currentTimeMillis() - start));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

之前都是通过地址,后来结合我的需求全部改成用流完成,还精简了代码。导出部分和word是同样的。
运行!测试通过!

poi模板导出pdf.png
这样看来一切都完工了呀!OK!交工!

然而并没有结束,还有后续。。。希望大家等待我后续的更新!

xx.jpg

想要jar包的可以关注公众号【两个二线城市的程序员】,回复【asposejar包】即可免费获得,后续有什么问题可以留言评论互动,我也只是一个小渣渣,不足支持也请各位大佬指点指点!(^▽^)