Freemarker+iText7用Java生成pdf文档,pdf添加图片,html转pdf

1.需求和技术选型

要求生成如下格式的报告,一共有十种。

因为本体是一个表格,所以大概的思路是用html画出这个表格,然后将html字符串转成pdf文件返回前端下载。技术方面选择用Freemarker画好html模板,然后后端把数值填好之后生成html字符串,最后把html字符串转成pdf文件返回前端下载。

2.依赖版本

Maven:freemarker:freemarker:2.3.1 
Maven:com.itextpdf.font-asian:7.1.13
Maven:com.itextpdf.html2pdf:3.0.2

1.完成模板文件template.ftl

freemarker部分语法:
============值
${data} data变量的值
============条件
<#if data == 10>
    <td colspan="3">
<#else if data == 15>
    <td colspan="4">
</#if>
============循环(其中可以用item_index获取下标,item_has_next获取是否有下一个)
<#list dataList as item>

</#list>

注意:该文件里的所有标签都要有闭合,包括<meta>或者<p>

2.从模板文件到html字符串

    /**
     * 根据Freemarker的Template生成Html字符串
     * @param templatePath 模板路径 例如 "E:\\INSPUR\\email\\untitled\\src\\main\\resources\\template"
     * @param templateName 模板文件名 例如"template1.ftl"
     * @param data         模板数据
     * @return String      html字符串
     * @throws IOException
     * @throws TemplateException
     */
    public static String generateHtmlStringByTemplate(String templatePath, String templateName, Object data) throws IOException, TemplateException {
        Configuration configuration = new Configuration();
        configuration.setDirectoryForTemplateLoading(new File(templatePath));
        configuration.setDefaultEncoding("UTF-8");
        StringWriter out = new StringWriter();
        Template template = configuration.getTemplate(templateName);
        template.process(data, out);
        String htmlText = out.toString();
        return htmlText;
    }

其中的data可以为Map对象,也可以为实体类 

3.从html字符串到pdf文件

    public static File convertHTMLToPDF(String htmlString) {
        File pdfFile = new File(SystemConstants.TARGET_PATH+"\\flag-5-photo-1-demo.pdf");
        try {
            PdfWriter pdfWriter = new PdfWriter(new FileOutputStream(pdfFile));
            PdfDocument pdfDocument = new PdfDocument(pdfWriter);
            ConverterProperties properties = new ConverterProperties();
            //添加中文字体支持
            FontProvider fontProvider = new FontProvider();
            PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
            fontProvider.addFont(sysFont.getFontProgram(), "UniGB-UCS2-H");
            properties.setFontProvider(fontProvider);
            InputStream inputStream = new ByteArrayInputStream(htmlString.getBytes(StandardCharsets.UTF_8));
            HtmlConverter.convertToPdf(inputStream, pdfDocument, properties);

            pdfWriter.close();
            pdfDocument.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pdfFile;
    }
SystemConstants.TARGET_PATH = "E:\\INSPUR\\email\\untitled\\src\\target";

方法第一行设置了生成的pdf文件的位置和文件名,itext没有自带的中文支持,所以要下载中文依赖,该方法返回的文件就是我们需要的pdf文件了,可以将其发送至前端下载。

4*.照片

表格中可能用用户传的图片,我们应将其合理排列,以下是期望效果。

一开始在往表格里插入图片的时候,图片总是带着恼人的空隙,导致一页放不下所有内容。后来我们用margin-top="- xx px"搞定。

具体实现如下:

模板部分:

        <tr>
            <th style="line-height: 105px;">设备照片</th>
            <td style="line-height: 100px" colspan="4">
                <#list equipmentPhotoSrcList as item>
                    <#assign isFirstRow = item_index lt 7>
                    <#assign isLastRow = item_index gte (listLength - (listLength % 7))>
                    <#assign isSingleRow = listLength lt 8>
                    <#if item_index % 7 == 0>
                        <div style="<#if isSingleRow>height: 100px;</#if><#if !isSingleRow && !isFirstRow && !isLastRow>margin-top: -40px;height: 65px;</#if><#if !isSingleRow && isLastRow>height: 105px;</#if>">
                    </#if>
                    <img src="${item}" height="100px" width="100px"></img>
                    <#if item_index % 7 == 6 || item_index == listLength - 1>
                        </div>
                    </#if>
                </#list>
            </td>
        </tr>

数据部分:

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值