Java指定格式的pdf导出

一、导出工具类

传入参数为需要渲染的数据,以及模板的位置。
需要准备好字体文件,同项目一起打包。可以在”控制面板\外观和个性化\字体“中找到想要的字体
其中工具类传入的参数示例为:

List<QuestionExportVO> questionExportVOList  = new ArrayList<>();          
Map<String, Object> data = new HashMap<>();
data.put("questionExportVOList", questionExportVOList);
baos = PDFTemplateUtil.createPDF(data, "QuestionReplyDetails.ftl");
public class PDFTemplateUtil {
    /**
     * 通过模板导出pdf文件
     *
     * @param data 数据
     * @throws Exception
     */
    public static ByteArrayOutputStream createPDF(Object data, String templateName) throws Exception {
        // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
        Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        // 指定FreeMarker模板文件的位置
        cfg.setClassForTemplateLoading(PDFTemplateUtil.class, "/templates");
        ITextRenderer renderer = new ITextRenderer();
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            // 设置 css中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示
            renderer.getFontResolver().addFont("/templates/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            renderer.getFontResolver().addFont("/templates/font/calibrib.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // 设置模板的编码格式
            cfg.setEncoding(Locale.CHINA, "UTF-8");
            // 获取模板文件
            Template template = cfg.getTemplate(templateName, "UTF-8");
            StringWriter writer = new StringWriter();

            // 将数据输出到html中
            template.process(data, writer);
            writer.flush();

            String html = writer.toString();
            // 把html代码传入渲染器中
            renderer.setDocumentFromString(html);
            renderer.layout();

            renderer.createPDF(out, false);
            renderer.finishPDF();
            out.flush();
            return out;
        }
    }
}

二、配置模板

根据需求画出想要的界面,注意并不是html,而是ftl格式(可以先画一个html,画出想要的格式后,再改造成ftl)。
其中有很多ftl格式才有的标签,用于实现数据渲染。可以做到动态增加表格,比如:

<#list detail.images as image>
          <#if image ??>
               <img style="width: 99%;padding-left: 2px;padding-top: 2px;" src="${image}" alt="image"/>
          </#if>
</#list>

<#list detail.images as image>代表在集合中循环操作,??代表如果对象存在(不为null)的话

${(child.conclusion)!''}则代表如果为null的时候,则用空字符串作为默认输出值

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8"/>
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: SimSun;
            padding: 30px 20px 0;
        }

        section {
            display: block;
        }

        .preface p {
            line-height: 30px;
            display: inline-block;
        }

        section > table {
            page-break-inside: auto;
            -fs-table-paginate: paginate;
            border-spacing: 0;
            cellspacing: 0;
            cellpadding: 0;
            border-collapse: collapse;
            table-layout: fixed;
            width: 100%;
            font-size: 13px;
            text-align: left;
            word-wrap: break-word;
        }

        section table td {
            padding: 5px 0;
        }

        section table tr {
            page-break-inside: avoid;
            page-break-after: auto;
        }

        .topTitle section {
            width: 30%;
            font-size: 13px;
            display: inline-block;
            margin-top: 20px;
        }

        .outTitle section {
            font-size: 13px;
            display: inline-block;
        }

        .detail {
            margin-top: 20px;
        }

        .box3 img {
            width: 100%;
        }

        .box3 p {
            font-size: 12px;
        }

        img {
            width: 50%;
        }
    </style>
</head>

<body>

<#if questionExportVOList ??>
    <section class="detail">
        <table border="1" cellspacing="0" cellpadding="0">
            <#list questionExportVOList as data>
                <tr style="font-weight: bold;font-size: 14px;text-align: center;">
                    <td colspan="2" width="100%">问题归属成果:${(data.stageOutcomeName)!''}</td>
                </tr>
                <#list data.questionDetails as detail>
                    <tr>
                        <td colspan="2" width="100%" style="font-family: Calibri;font-weight: bold;font-size: 12px;background-color:yellow;">&nbsp;&nbsp;${(detail.serialNumber)!''}</td>
                    </tr>
                    <tr>
                        <th rowspan="7">
                            <#list detail.images as image>
                                <#if image ??>
                                    <img style="width: 99%;padding-left: 2px;padding-top: 2px;" src="${image}" alt="image"/>
                                </#if>
                            </#list>

                        </th>
                        <td><b style="font-size: 12px;">问题所属图纸或模型:</b>${(detail.fileName)!''}</td>
                    </tr>
                    <tr>
                        <td><b style="font-size: 12px;">问题标题:</b>${(detail.questionTitle)!''}</td>
                    </tr>
                    <tr>
                        <td><b style="font-size: 12px;">问题描述:</b>${(detail.questionDesc)!''}</td>
                    </tr>
                    <tr>
                        <td>专业:${(detail.major)!''}</td>
                    </tr>
                    <tr>
                        <td>知悉人员:${(detail.knowingStaff)!''}</td>
                    </tr>
                    <tr>
                        <td>主责人员:${(detail.participants)!''}</td>
                    </tr>
                    <tr>
                        <td>上传附件:${(detail.attachmentName)!''}</td>
                    </tr>
                    <#if detail.children ??>
                        <#list detail.children as child>
                            <tr style="font-weight: bold;font-size: 12px;">
                                <td colspan="2" width="100%">${(child.operate)!''}</td>
                            </tr>
                            <#if child.conclusion ??>
                                <tr>
                                    <td>复核人员:${(child.createBy)!''}</td>
                                    <#if child.conclusion == "同意">
                                        <td>复核结论:<b style="color: green;">${(child.conclusion)!''}</b></td>
                                    <#else >
                                        <td>复核结论:<b style="color: red;">${(child.conclusion)!''}</b></td>
                                    </#if>
                                </tr>
                            <#else >
                                <tr>
                                    <td colspan="2" width="100%">回复人员:${(child.createBy)!''}</td>
                                </tr>
                            </#if>
                            <#if child.replyContent ??>
                                <tr>
                                    <td colspan="2" width="100%">${(child.replyContent)!''}</td>
                                </tr>
                            </#if>
                        </#list>
                    </#if>
                </#list>
            </#list>
        </table>
    </section>
</#if>

</body>

</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容