zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    去除vue-router 链接上的#号
    input 实现调用本地摄像头 实现拍照 和拍视频
    vue-cli 安装sass 和 font-awesome 笔记
    linux下alias命令详解
    linux下source命令的基本功能
    在Linux命令行窗口中,怎么向上翻页?
    Android内存监测工具使用
    Activity的Theme主题风格
    ListView中CheckBox错乱解决
    绘图之Canvas学习
  • 原文地址:https://www.cnblogs.com/yy123/p/11391124.html
Copyright © 2011-2022 走看看