iText + freemarkerは、ローカルpdfファイルを生成せずにpdfバイトストリーム印刷に変換します

iText + freemarkerは、ローカルpdfファイルを生成せずにpdfバイトストリーム印刷に変換します

  1. このプロジェクトは、springbootプロジェクトの依存関係を紹介します
<!-- 模板引擎 代码生成 -->
<dependency>
   <groupId>org.apache.velocity</groupId>
   <artifactId>velocity-engine-core</artifactId>
   <version>${
    
    velocity-engine.version}</version>
</dependency>

<!-- freemarker 模板引擎 -->
<dependency>
   <groupId>org.freemarker</groupId>
   <artifactId>freemarker</artifactId>
   <version>${
    
    freemarker.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf 对itext的支持-->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.11</version>
</dependency>

2.操作ツール

	private static final String FONT = "font/simhei.ttf";
 /**
     * pdf 字节流响应
     *
     * @param response
     * @param result pdf字节输出流 字符串
     * @throws IOException
     */
    public static void pdfResponse(HttpServletResponse response, String result) throws IOException {
    
    
        //如果跨域需设置解码
        result = URLDecoder.decode(result, "ISO-8859-1");
        ByteArrayInputStream inStream = new ByteArrayInputStream(result.getBytes("ISO-8859-1"));
        // 循环取出流中的数据
        byte[] b = new byte[2048];
        int len;
        try {
    
    
            while ((len = inStream.read(b)) > 0) {
    
    
                response.getOutputStream().write(b, 0, len);
            }
            inStream.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 生成pdf
     *
     * @param content freemarker 渲染后输出的文本
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static String createPdf(String content) throws IOException, DocumentException {
    
    
        Rectangle rectPageSize = new Rectangle(PageSize.A4);
        // step 1
        Document document = new Document(rectPageSize);
        // step 2
        //构建字节输出流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontImp.register(FONT);
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
        // step 5
        document.close();
        baos.close();
        //转字符串设置编码
        String result = new String(baos.toByteArray(), "ISO-8859-1");
        return URLEncoder.encode(result, "ISO-8859-1");//如果跨域需设置编码
    }

    /**
     * 生成pdf
     * @param content freemarker 渲染后输出的文本
     * @param dest 生成pdf所在文件位置
     * @throws IOException
     * @throws DocumentException
     */
    public void createPdf(String content, String dest) throws IOException, DocumentException {
    
    
        Rectangle rectPageSize = new Rectangle(PageSize.A4);
        Document document = new Document(rectPageSize);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        document.open();
        XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontImp.register(FONT);
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
        document.close();
    }

    /**
     * freemarker 渲染 html
     *
     * @param data    数据 Map<String,Object>
     * @param htmlTmp 模板名称
     * @return
     */
    public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
    
    
        Configuration freemarkerCfg = new Configuration();
        //freemarker的模板目录 "/freemakertemplate/"
        try {
    
    
            freemarkerCfg.setDirectoryForTemplateLoading(new File(FileUtil.class.getResource("/").getPath() + "/freemakertemplate"));
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        Writer out = new StringWriter();
        try {
    
    
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(htmlTmp);
            template.setEncoding("UTF-8");
            // 合并数据模型与模板
            //将合并后的数据和模板写入到流中,这里使用的字符流
            template.process(data, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                out.close();
            } catch (IOException ex) {
    
    
                ex.printStackTrace();
            }
        }
        return null;
    }

    /**
     *  pdf 打印
     * @param data
     * @param freemarkertemplate
     * @param response
     */
    public static void printPdf(Map<String, Object> data, String freemarkertemplate, HttpServletResponse response) {
    
    
        //freemarker 模板渲染
        String content = freeMarkerRender(data,freemarkertemplate);
        try {
    
    
            String result = createPdf(content);
            pdfResponse(response,result);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (DocumentException e) {
    
    
            e.printStackTrace();
        }
    }

3.データを構築するためのコントローラーレイヤー呼び出し
ここに画像の説明を挿入
4.テンプレートとフォントのディレクトリ構造
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/u011445756/article/details/87381983