ftl转pdf及问题集锦

这是一个令人悲伤的问题,本人在网上大量查找资料,总是有这样那样的问题导致不能转换成功

引入的maven     jar包如下

    <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>core-renderer</artifactId>
            <version>R8</version>
        </dependency>

 

参考了很多资料,我选择的是  https://blog.csdn.net/NetSnake_/article/details/77161106   作为参考

@RequestMapping("/printingcontractNew")
    public void printingcontractNew( HttpServletResponse response,Long orderId,HttpServletRequest request) throws Exception {


        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderContract", order);
        map.put("orderinformation", orderinformation);

      //输入需要传输的数据
        try {
            ByteArrayOutputStream baos = FtlToPdf1.createPDF(request, "PrintingContract.ftl", map);    //"PrintingContract.ftl"为自己的ftl能展示的(注意结构必须严谨)
            System.out.println(baos);
            //设置response文件头
             FtlToPdf1.renderPdf(response, baos.toByteArray(), "789");    //789  为输出pdf的名字可以自己命名
        } catch (Exception e) {
            throw new Exception(e);
        }


      /*  ftlTOPDF.FTL2PDF(srcPath, destPath, map);*/
    }
package com.ningpai.site.pdf;

/*import com.lowagie.text.pdf.BaseFont;*/

import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.itextpdf.text.Font;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
/*
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
*/

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Created by Administrator on 2018-5-19.
 */
public class FtlToPdf1 {

    /**
     * 生成PDF文件流
     * @param request
     * @param ftlName 文件名称
     * @param root  数据
     * @return ByteArrayOutputStream
     * @throws Exception
     */
    public static ByteArrayOutputStream createPDF(HttpServletRequest request, String ftlName, Object root) throws Exception {
        String basePath = request.getSession().getServletContext().getRealPath("/");//绝对路径
        Configuration cfg = new Configuration();
        try {
            cfg.setLocale(Locale.CHINA);
            cfg.setEncoding(Locale.CHINA, "UTF-8");
            //设置编码
            cfg.setDefaultEncoding("UTF-8");
            //设置模板路径
            cfg.setDirectoryForTemplateLoading(new File(basePath + "view/contract/"));

            //获取模板
            Template template = cfg.getTemplate(ftlName);
            template.setEncoding("UTF-8");

            ITextRenderer iTextRenderer = new ITextRenderer();
            //设置字体
            ITextFontResolver fontResolver = iTextRenderer.getFontResolver();
            fontResolver.addFont(basePath + "view/contract/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);    "view/contract/simsun.ttf"  为下载的字体将其放入程序中的位置

            Writer writer = new StringWriter();
            //数据填充模板
            template.process(root, writer);
            //设置输出文件内容及路径
            String str = writer.toString();
            iTextRenderer.setDocumentFromString(str);
            iTextRenderer.getSharedContext().setBaseURL("file:/D:");  //图片共享路径file:/home/ddcj/
            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) {
        setFileDownloadHeader(response, filename, ".pdf");
        if (null != bytes) {
            try {
                response.getOutputStream().write(bytes);
                response.getOutputStream().flush();
            } catch (IOException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

    /**
     * 设置让浏览器弹出下载对话框的Header.
     * @param fileName 下载后的文件名.
     */
    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) {
        }
    }
}

效果图如下:

点击打印

 

 

打开后

 

 格式有点丑,还没开始修改...

 

 

问题集锦:

1.org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException; lineNumber: 167; columnNumber: 44; 元素类型 "td" 必须由匹配的结束标记 "</td>" 终止。

报错的代码如下:

   <tr>
                    <td class="product_table_th">供方:xxx</br>地址:xxx</br>电话:028-3xxxx59</br>传真:028-xxxxx909</br>
                        开户银行:中国建设xxx分行</br>账号:5100 xxxx xxxx xxx1 0200
                    </td>
                    <td class="product_table_th">需方:${orderinformation.invoiceCompanyName}</br>地址:${orderinformation.invoiceSite} </br>
                        电话:${orderinformation.invoicePhoneNumber}</br>传真:</br>
                        开户银行:${orderinformation.invoiceDepositBank}</br>账号:${orderinformation.invoiceBankAccount} </td>
                </tr> 

想做成的效果

经过多次查找,发现没什么问题;页面也能正常的显示,但就是会再转pdf时报错

最后无意间修改解决了问题

 <tr>
                    <td class="product_table_th">供方:四川xxxx有限公司<br></br>地址:xxxx开发区<br></br>电话:028-xxxx59<br></br>传真:028-3xxxx09<br></br>
                        开户银行:中国xxx分行<br></br>账号:5100 xxxxx 0200
                    </td>
                    <td class="product_table_th">需方:${orderinformation.invoiceCompanyName}<br></br>地址:${orderinformation.invoiceSite} <br></br>
                        电话:${orderinformation.invoicePhoneNumber}<br></br>传真:<br></br>
                        开户银行:${orderinformation.invoiceDepositBank}<br></br>账号:${orderinformation.invoiceBankAccount} </td>
                </tr>

重点为<br></br>  因为itex转pdf是非常严谨的必须有开头和结尾

 

2.org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException; lineNumber: 89; columnNumber: 45; 元素类型 "td" 必须后跟属性规范 ">" 或 "/>"。

报错代码为

 <tr>
                    <td class="product_table_th">备注</td>
                    <td class="product_table_th"colspan="5"> ${orderinformation.customerRemark} </td>
                </tr>

原因居然是

这。。。尼....果然严谨

3.  本因分开的结果没有分开对应显示

错误代码

    <#list orderContract as good>
                <thead align="center">
                    <tr>
                        <td class="product_table_th"><span>${good.goodsInfoName}</span></td>
                        <td class="product_table_th"><span>${good.goodsInfoNum}</span></td>
                        <td class="product_table_th"><span>件</span></td>
                        <td class="product_table_th"><span>${good.goodsInfoPrice}</span></td>
                        <td class="product_table_th"><span>${good.goodsInfoSumPrice}</span></td>
                    </tr>
                </thead>
                </#list>

原因:加入了<thead align="center">属性,,,注释掉就好

 4.只显示数字和英文    ,  中文字符不显示问题

在网上查了很多,各方面的问题解决方法都有

我的问题是

<?xml version="1.0" encoding="UTF-8"?>
<!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>合同打印预览</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
    <meta name="renderer" content="webkit"></meta>
</head>

<body style="font-size:12.0pt; font-family: SimSun; background: none;margin-left: auto;margin-right: auto">
<table.....>
...

主要是这个      <body style="font-size:12.0pt; font-family: SimSun; background: none;margin-left: auto;margin-right: auto">   加上就好了

 

转载于:https://www.cnblogs.com/huanglp/p/9061046.html

### 回答1: Java FTL生成PDF是一种将FreeMarker模板和Java代码结合使用的技术,用于生成PDF文件。FreeMarker是一个模板引擎,它提供了模板的定义和数据的注入机制,可以将模板与数据结合起来生成输出内容。 在Java中使用FTL生成PDF的过程通常包括以下几个步骤: 1. 导入所需的JavaFTL库:首先,需要在Java项目中引入相应的FTL库,以及用于生成PDF的相关Java库,例如iText。这些库可以通过Maven等构建工具进行导入。 2. 创建FreeMarker模板:使用FreeMarker模板定义需要生成PDF的样式和格式。模板中可以包含静态内容,也可以通过模板语言标记占位符,用于插入动态数据。 3. 编写Java代码:在Java中,通过调用FreeMarker库的相关类和方法,可以将数据与模板进行合并,生成包含动态数据的文本内容。 4. 生成PDF文件:在得到合并后的文本内容后,使用iText等相关Java库将文本内容化为PDF格式。这些库提供生成PDF的方法和API,可以指定生成的PDF文件的路径和样式。 使用Java FTL生成PDF的好处是,可以通过模板和数据分离的方式,实现PDF的动态生成,从而提高开发效率和灵活性。通过模板的复用,可以实现对于不同数据的PDF生成,从而满足不同的需求。同时,使用Java的优势也能够提供更多的功能和扩展性,比如添加图片、表格等多样化的内容。 当然,需要注意的是,Java FTL生成PDF仍然需要对Java和FreeMarker的使用有一定的了解和掌握。在使用过程中,也需要关注文件路径、字体设置、编码等细节,以确保生成的PDF文件符合预期的要求。 ### 回答2: Java FTL(FreeMarker Template Language)可以用来生成PDF文件。FTL是一种模板语言,常用于生成动态的网页内容。但是,我们也可以通过将FTL模板与相应的数据进行结合,然后使用Java代码来渲染模板并生成PDF文件。 首先,我们需要设置一个FTL模板,其中包含我们想要在PDF中显示的内容。这个模板可以包含HTML标记和FTL标签,用于在生成PDF时插入动态数据。 然后,我们需要在Java代码中使用FreeMarker库来实现模板的渲染和生成PDF文件的功能。这可以通过以下步骤完成: 1. 创建一个Configuration对象,并设置模板文件的路径。这将告诉FreeMarker在哪里查找FTL模板文件。 2. 使用Configuration对象创建一个Template对象,将需要使用的模板文件作为参数传递给它。 3. 创建一个Writer对象,用于将生成的PDF内容写入。 4. 创建一个Map对象,并将需要在FTL模板中使用的数据放入其中。这些数据将替换模板中的FTL标签。 5. 使用Template对象的process方法,将Map对象和Writer对象作为参数传递给它。这将生成PDF文件的内容并将其写入Writer对象。 6. 最后,将Writer对象中的内容写入到PDF文件中,完成PDF文件的生成。 总结起来,通过使用JavaFTL模板,我们可以生成动态的PDF文件。首先设置好模板文件,然后使用Java代码来渲染模板并将数据填充到模板中,最后将生成的内容写入到PDF文件中即可。 ### 回答3: Java与FreeMarker模板引擎(FTL)可以结合生成PDF文档。具体过程如下: 首先,我们需要使用Java的相关库来操作PDF文档。常用的库有iText、Apache PDFBox等。这些库提供了一些API来创建、编辑和保存PDF文件。 其次,我们需要准备好FTL模板文件。FTL是一种模板引擎语言,可以将数据动态地填充到模板中,生成相应的输出文本。 然后,我们需要在Java代码中使用FTL模板引擎。Java中有一些FTL模板引擎的实现,比如FreeMarker和Velocity。我们可以选择其中之一,然后使用相应的API来加载模板文件。 接下来,我们需要准备数据。通过Java代码,我们可以从数据库、文件或其他资源中获取数据。然后,将数据与FTL模板进行结合,填充到模板中。 最后,我们使用PDF库的API将生成的文本保存为PDF文件。根据选择的PDF库,可能会有一些具体的步骤和API调用。 总结来说,使用JavaFTL模板引擎生成PDF的过程包括准备PDF库、准备FTL模板文件、使用Java代码加载模板、准备数据并填充到模板中,最后使用PDF库将生成的文本保存为PDF文件。这样,我们就可以通过JavaFTL生成PDF文档了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值