freemarket+itext+springboot将html静态页面渲染后导出为pdf文件

1、maven依赖

       <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>core-renderer</artifactId>
            <version>R8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>

    </dependency>
2、controller

@RequestMapping(value = "projectExport", method = RequestMethod.GET)
    public void projectExport(HttpServletRequest request, HttpServletResponse response) {
        try {

            Map map=new HashMap<String,Object>();
            map.put("test","测试");

            ByteArrayOutputStream baos = PDFUtil.createPDF("templates/project.html", map);
            //设置response文件头

            PDFUtil.renderPdf(response, baos.toByteArray(), "pdf文件");
            baos.close();
        } catch (Exception e) {
            logger.info("导出报错",e);
        }
    }
3、PDFUtil

import com.itextpdf.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Locale;

/**
 * PDF工具类
 * @author LQX
 *
 */
public class PDFUtil {

    private static String DEFAULT_ENCODING="utf-8";
    private static String PDF_TYPE="application/pdf";
    private static boolean DEFAULT_NOCACHE=true;
    private static String HEADER_ENCODING="utf-8";
    private static String HEADER_NOCACHE="no-cache";

    /**
     * 生成PDF文件流
     * @param ftlName 文件名称
     * @param root    数据
     * @return ByteArrayOutputStream
     * @throws Exception
     */
    public static ByteArrayOutputStream createPDF(String ftlName, Object root) throws Exception {
        //相对路径
        File file = new File(PDFUtil.class.getResource("/").getPath());
        Configuration cfg = new Configuration();
        try {
            cfg.setLocale(Locale.CHINA);
            cfg.setEncoding(Locale.CHINA, "UTF-8");
            //设置编码
            cfg.setDefaultEncoding("UTF-8");
            //设置模板路径
            cfg.setDirectoryForTemplateLoading(file);
            //获取模板
            Template template = cfg.getTemplate(ftlName);
            template.setEncoding("UTF-8");
            ITextRenderer iTextRenderer = new ITextRenderer();
            //设置字体
            ITextFontResolver fontResolver = iTextRenderer.getFontResolver();
            fontResolver.addFont(file.getPath() + "/public/font/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            Writer writer = new StringWriter();
            //数据填充模板
            template.process(root, writer);
            //设置输出文件内容及路径
            String str = writer.toString();
            iTextRenderer.setDocumentFromString(str);
            /*iTextRenderer.getSharedContext().setBaseURL("");//共享路径*/
            iTextRenderer.layout();
            //生成PDF
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            iTextRenderer.createPDF(baos);
            baos.close();
            return baos;
        } catch(Exception e) {
            throw new Exception(e);
        }
    }
    public static void renderPdf(HttpServletResponse response, final byte[] bytes, final String filename) {
        initResponseHeader(response, PDF_TYPE);
        setFileDownloadHeader(response, filename, ".pdf");
        if (null != bytes) {
            try {
                response.getOutputStream().write(bytes);
                response.getOutputStream().flush();
            } catch (IOException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

    /**
     * 分析并设置contentType与headers.
     */
    private static HttpServletResponse initResponseHeader(HttpServletResponse response, final String contentType, final String... headers) {
        // 分析headers参数
        String encoding = DEFAULT_ENCODING;
        boolean noCache = DEFAULT_NOCACHE;
        for (String header : headers) {
            String headerName = StringUtils.substringBefore(header, ":");
            String headerValue = StringUtils.substringAfter(header, ":");
            if (StringUtils.equalsIgnoreCase(headerName, HEADER_ENCODING)) {
                encoding = headerValue;
            } else if (StringUtils.equalsIgnoreCase(headerName, HEADER_NOCACHE)) {
                noCache = Boolean.parseBoolean(headerValue);
            } else {
                throw new IllegalArgumentException(headerName + "不是一个合法的header类型");
            }
        }
        // 设置headers参数
        String fullContentType = contentType + ";charset=" + encoding;
        response.setContentType(fullContentType);
        if (noCache) {
            // Http 1.0 header
            response.setDateHeader("Expires", 0);
            response.addHeader("Pragma", "no-cache");
            // Http 1.1 header
            response.setHeader("Cache-Control", "no-cache");
        }
        return response;
    }

    /**
     * 设置让浏览器弹出下载对话框的Header.
     * @param
     */
    public static void setFileDownloadHeader(HttpServletResponse response, String fileName, String fileType) {
        try {
            // 中文文件名支持
            String encodedfileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + fileType + "\"");
        } catch (UnsupportedEncodingException e) {
        }
    }
}
3、project.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>PDF下载</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style mce_bogus="1" type="text/css">
            body {font-family: SimSun; }
            @page {size: 800mm 400mm}
        </style>
    </head>
    <body>
        <table width="100%" height="60" border="0" align="center" cellpadding="0" cellspacing="0">
            <tr>
                <td>12345</td>
                <td>${test}</td>
                <td>abc</td>
            </tr>
        </table>
    </body>
</html>
需要注意的点:

(1)、中文字体

html中要将body标签的字体设置为SimSun,然后项目中要放这个字体文件,因为服务器中通常没有这个文件,simsun.ttf字体百度上都可以下载。只有设置了字体后html中的中文才能识别出来。

(2)、css文件

如果你想导的pdf文件的样式是css渲染后的页面样式,一定要注意link中css引用的路径,通常用服务器的绝对路径,你也可以自己换一换路径试试。导出时会因为一些外部的文件的路径写的不对而出现空指针异常,可以先把这些都注释掉再调试。

(3)、html标签

这个工具导出的时候对html标签的要求比较的严格,比如一些闭合标签一定要写完整,href链接中直接请求接口带参数的时候有&连接的时候要在&后面加上amp;

(4)、pdf文件的大小

给这个html文件加上css样式@page {size:800mm 400mm}这个样式可以调整pdf的文件,因为我导出的时候宽度达不到我想要的宽度,但是我还是不会动态的去设置这个大小,欢迎知道的小伙伴指教。
 ————————————————
原文链接:https://blog.csdn.net/haha_66666/article/details/83025919

原文地址:https://www.cnblogs.com/yy123/p/11391124.html

时间: 2024-08-02 04:15:23

freemarket+itext+springboot将html静态页面渲染后导出为pdf文件的相关文章

页面直接导出为PDF文件,支持分页与页边距

将WEB页面直接导出为pdf文件是经常会用到的一个功能,尤其是各种报表系统.总结了一下目前几种主流的做法: 在后端用代码生成pdf文件,比如iText一类: 在后端抓取页面并生成pdf文件,比如phantomjs一类: 在前端用js直接生成pdf文件: 方案3的优势在于前端直接生成,所见即所得.今天要探索的就是html2canvas和jspdf,前者用于将页面元素render生成canvas,后者用于将canvas生成pdf文档.需要注意的是,这种方法对IE系列支持不好. html2canvas

将w3cplus网站中的文章页面提取并导出为pdf文档

最近在看一些关于CSS3方面的知识,主要是平时看到网页中有很多用CSS3实现的很炫的效果,所以就打算系统的学习一下.在网上找到很多的文章,但都没有一个好的整理性,比较凌乱.昨天看到w3cplus网站中关于CSS3的一些文章,觉得讲解的比较细,所以就决定以此作为学习的模板,一步步开始. 平时上下班在地铁上经常是拿着手机看小说新闻之类的,考虑到在手机端直接访问这些网页肯定会耗费很大的流量,所以最好是将这些文章下载下来放在手机里看,比如保存成图片或pdf当然是最好的选择. 之前曾在园子里看到某前端高手

PHP代码为什么不能直接保存HTML文件——&amp;gt;PHP生成静态页面教程

1.server会依据文件的后缀名去进行解析,假设是HTML文件则server不会进行语法解析.而是直接输出到浏览器. 2.假设一个页面中所有都是HTML代码而没有须要解析的PHP语法,则没有必要保存为PHP文件,这样反而会减少执行效率. 3.假设是须要PHP控制HTML代码的输出,比方须要PHP推断用户是否登陆,假设登陆则输出A,未登录则输出B.这就须要PHP来进行控制了.HTML不能实现这种功能 PHP生成静态页面教程 ,一些主要的概念 一,PHP脚本与动态页面. PHP脚本是一种serve

浅谈php生成静态页面

一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权限限制等,但是,对应一些我们经常频频使用的文件,比方说,开发的新闻发布系统,我们不希望很多用户都读取数据库才显示结果,这样一方面消耗了服务器的资源,另一方面占去了浏览者大量可贵的响应时间,所有,有了"静态页面话"的做法,当前很多网站都采用这种技术,一般都是由管理后台控制,或者生成html直

通过前端js将页面表格导出为PDF(二)

前面我说道了,将页面的表格导出为pdf,通过我给出的代码完好的实现了其需求,但是没过几天,又说不行了,因为我的表格是按照最多26行就进行分页,如果表格行数一多,就要点击下一页再进行pdf的导出,因为是面向客户的,所以要尽量减少用户的操作,因此要改成,一键导出所有的表格,然后自动分页,每页再加上特定的图片.我就日了@#@#@!这是....,没办法,改呗,前前后后折腾了两天,终于让我给整出来了,不容易啊!真的的是有需求才有动力啊! 先说一下我的方式:首先还是按照正常的进行分页显示,当点击导出pdf按

如何旋转PDF文件的页面,一种非常简单的方法。

如何旋转PDF文件页面呢?在使用PDF文件的时候,有很多的页面是歪的,想要将这些页面旋转就可以使用迅捷PDF编辑器,下面就为大家分享一下迅捷PDF编辑器如何进行PDF旋转页面的操作. 操作软件:迅捷PDF编辑器 具体操作方法: 1:将PDF编辑器安装到自己的电脑中,打开软件找到打开更多文件,将需要旋转页面的PDF文件添加到软件中来. 2:在软件的界面找到文档,点击文档在下面的下拉框中可以找到旋转页面. 3:点击选择页面,在软件中会出现一个选择框,在选择框中可以设置旋转的方向,可以为顺时针90度也

PDF编辑器如何拆分PDF文件页面

PDF编辑器如何拆分PDF文件页面呢?很多实用PDF文件的人都会对PDF页面拆分感到很烦恼,也就是因为PDF文件不可以直接进行编辑,其实想要进行PDF文件页面拆分就可以使用到迅捷PDF编辑器,下面小编就为大家操作一下PDF编辑器如何拆分PDF页面. 操作软件:迅捷PDF编辑器 具体操作方法: 1:首先将PDF编辑器安装到电脑中,打开PDF编辑器,将需要编辑的PDF文件添加到软件中. 2:在软件中可以找到文档,点击文档在下面找到更多页面,将鼠标移动到更多页面,在右侧可以找到拆分页面. 3:点击拆分

网页开发方式-从静态页面到服务端渲染

前言 网页的最初形式就是一个个静态页面,例如我们写了一个 html 文件,放在服务器上就可以供用户访问了. 而后网站变得需要展示更多的内容,让内容更加动态,因此需要接入数据库,配合数据库的内容做展示,于是诞生了 html 模板引擎,用于把动态的数据插入到 html 中,叫做动态页面,后面我会叫它为传统的动态页面,例如 java 的 Jsp,php 的 Smarty 和 node 的 Jade 等. 再后来伴随浏览器的发展,网页交互变得越来越复杂等一系列原因,前端技术突飞猛进,诞生了前后端分离的单

SpringBoot学习------SpringBoot使用Thymeleaf模块访问不了静态页面

SpringBoot使用Thymeleaf模块访问不了静态页面 最近学习SpringBoot的过程中使用了Thymeleaf模块引擎,页面发送请求后老是无法显示静态页面,所有的步骤都是参考资料来执行,自我检查好久都没有找到问题的答案,哎呦,我这暴脾气就上来了,一个小页面就想难倒我?那我还怎么找到ONE PIECE? 下面就给大家分享一下我悲惨的心路历程: 要使用Thymeleaf模块引擎,我们首先在pom文件中引入相关依赖如下: 这边我们不需要指定版本,因为SpringBoot默认会使用spri