IText+FreeMarker导出PDF

PDF生成工具类

package com.zhongan.life.printer.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.zhongan.life.printer.common.Common500Exception;
import com.zhongan.life.printer.common.CommonException;
import com.zhongan.life.printer.common.enums.DtcErrorEnum;
import com.zhongan.life.printer.model.dto.printer.request.PdfPrintParam;
import com.zhongan.life.printer.service.configs.FontProviderConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

@Slf4j
public class PDFKit {

    //PDF页眉、页脚定制工具
    private HeaderFooterBuilder headerFooterBuilder;

    /**
     * @param fileName 输出PDF文件名
     * @param data     模板所需要的数据
     * @description 导出pdf到文件
     */
    public String exportToFile(String fileName, Object data, Path templatePath) throws IOException {
        // 获取临时路径
        Path pdfFilePath = Files.createTempFile(fileName, ".pdf");
        FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
        // freeMarker 转换
        String htmlData = freeMarkerUtil.getContent(fileName, data, templatePath);
        FileOutputStream outputStream = null;
        try {
            //设置输出路径
            outputStream = new FileOutputStream(pdfFilePath.toFile());
            //设置文档大小
            Document document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //设置页眉页脚
            PDFBuilder builder = new PDFBuilder(headerFooterBuilder, data);
            builder.setPresentFontSize(10);
            writer.setPageEvent(builder);
            //输出为PDF文件
            convertToPDF(writer, document, htmlData);
            return pdfFilePath.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("exportToFile:{}", ex.getMessage());
            throw new Common500Exception(DtcErrorEnum.PDF_GENERATION_ERROR, ExceptionUtils.getFullStackTrace(ex));
        } finally {
            // 删除模板的临时文件
            IOUtils.closeQuietly(outputStream);
        }
    }


    /**
     * @description PDF文件生成
     */
    private void convertToPDF(PdfWriter writer, Document document, String htmlString) {
        //获取字体路径
//        String fontPath = getFontPath();
        document.open();
        try {
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                    new ByteArrayInputStream(htmlString.getBytes("UTF-8")),
                    null,
                    Charset.forName("UTF-8"), new FontProviderConfig());
        } catch (IOException e) {
            throw new CommonException(DtcErrorEnum.IOEXCEPTION);
        } finally {
            document.close();
        }

    }

    /**
     * @description 创建默认保存路径
     */
    private String getDefaultSavePath(String fileName) {
        String classpath = PDFKit.class.getClassLoader().getResource("").getPath();
        String saveFilePath = classpath + "pdf/" + fileName;
        File f = new File(saveFilePath);
        if (!f.getParentFile().exists()) {
            f.mkdirs();
        }
        return saveFilePath;
    }

    /**
     * @description 获取字体设置路径
     */
    public static String getFontPath() {
        String classpath = PDFKit.class.getClassLoader().getResource("").getPath();
        String fontpath = classpath + "fonts";
        return fontpath;
    }

    public HeaderFooterBuilder getHeaderFooterBuilder() {
        return headerFooterBuilder;
    }

    public void setHeaderFooterBuilder(HeaderFooterBuilder headerFooterBuilder) {
        this.headerFooterBuilder = headerFooterBuilder;
    }

}

package com.zhongan.life.printer.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * PDF页眉页脚
 */
public interface HeaderFooterBuilder {


    /**
     * @description 写页眉
     */
    void writeHeader(PdfWriter writer, Document document, Object data, Font font, PdfTemplate template);
    /**
     * @description 写页脚
     */
    void writeFooter(PdfWriter writer, Document document, Object data, Font font, PdfTemplate template);

    /**
     * @description 关闭文档前,获取替换页眉页脚处设置模板的文本
     */
    String  getReplaceOfTemplate(PdfWriter writer, Document document, Object data);

}
package com.zhongan.life.printer.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * 页眉页脚定制工具
 */
public class PDFHeaderFooter implements HeaderFooterBuilder {
    /**
     * @param writer   PDF编写类
     * @param document PDF文档对象
     * @param data     业务数据
     * @param font     字体设置
     * @param template PDF模板
     * @description PDF页脚设置类
     */
    @Override
    public void writeFooter(PdfWriter writer,
                            Document document,
                            Object data,
                            Font font,
                            PdfTemplate template) {
        if (data == null) {
            return;
        }
        int pageS = writer.getPageNumber();
//        int currentPage = pageS - 1;
//        if (currentPage <= 0) {
//            return;
//        }
        Phrase footer1 = new Phrase("页脚一", font);
        Phrase footer2 = new Phrase("页脚二" + "    " + pageS + "/", font);

        PdfContentByte cb = writer.getDirectContent();
        ColumnText.showTextAligned(
                cb,
                Element.ALIGN_LEFT,
                footer1,
                (document.left() + 10),
                document.bottom() - 20,
                0);
        ColumnText.showTextAligned(
                cb,
                Element.ALIGN_RIGHT,
                footer2,
                (document.right() - 30),
                document.bottom() - 20, 0);

        //设置模板位置
        cb.addTemplate(template, document.right() - 30, document.bottom() - 20);

    }

    /**
     * @param writer   PDF编写类
     * @param document PDF文档对象
     * @param data     业务数据
     * @param font     字体设置
     * @param template PDF模板
     * @description PDF页头设置类
     */
    @Override
    public void writeHeader(PdfWriter writer,
                            Document document,
                            Object data,
                            Font font,
                            PdfTemplate template) {

        ColumnText.showTextAligned(
                writer.getDirectContent(),
                Element.ALIGN_LEFT,
                new Phrase("众安国际", font),
                document.left(),
                document.top() + 20, 0);


    }


    /**
     * @param writer   PDF编写类
     * @param document PDF文档对象
     * @param data     业务数据
     * @description 页头、页眉设置的模板替换类
     */
    @Override
    public String getReplaceOfTemplate(PdfWriter writer, Document document, Object data) {
        int total = writer.getPageNumber() - 2;
        return total + "";
    }

}
package com.zhongan.life.printer.utils;

import com.google.common.collect.Maps;
import com.zhongan.life.printer.common.CommonException;
import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.file.Path;
import java.util.Map;

/**
 * 
 * FREEMARKER 模板工具类
 */
@Slf4j
@Component
public class FreeMarkerUtil {
    private static final String WINDOWS_SPLIT = "\\";

    private static final String UTF_8 = "UTF-8";

    private static Map<String, FileTemplateLoader> fileTemplateLoaderCache = Maps.newConcurrentMap();

    private static Map<String, Configuration> configurationCache = Maps.newConcurrentMap();

    public static Configuration getConfiguration(String templateFilePath) {
        if (null != configurationCache.get(templateFilePath)) {
            return configurationCache.get(templateFilePath);
        }

        Configuration config = new Configuration(Configuration.VERSION_2_3_25);
        config.setDefaultEncoding(UTF_8);
        config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        config.setLogTemplateExceptions(false);
        FileTemplateLoader fileTemplateLoader = null;
        if (null != fileTemplateLoaderCache.get(templateFilePath)) {
            fileTemplateLoader = fileTemplateLoaderCache.get(templateFilePath);
        }
        try {
            fileTemplateLoader = new FileTemplateLoader(new File(templateFilePath));
            fileTemplateLoaderCache.put(templateFilePath, fileTemplateLoader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        config.setTemplateLoader(fileTemplateLoader);
        configurationCache.put(templateFilePath, config);
        return config;

    }

    /**
     * @description 获取模板
     */
    public String getContent(String fileName, Object data, Path templatePath) {
        try (StringWriter writer = new StringWriter();) {
            String templateFileName = getTemplateName(templatePath.toString());
            String templateFilePath = getTemplatePath(templatePath.toString());
            Template template = getConfiguration(templateFilePath).getTemplate(templateFileName);
            template.process(data, writer);
            writer.flush();
            return writer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new CommonException("", "FreeMarkerUtil process fail", ex.getMessage());
        }
    }


    private String getTemplatePath(String templatePath) {
        if (StringUtils.isEmpty(templatePath)) {
            return "";
        }
        if (templatePath.contains(WINDOWS_SPLIT)) {
            return templatePath.substring(0, templatePath.lastIndexOf(WINDOWS_SPLIT));
        }
        return templatePath.substring(0, templatePath.lastIndexOf("/"));
    }

    private String getTemplateName(String templatePath) {
        if (StringUtils.isEmpty(templatePath)) {
            return "";
        }
        if (templatePath.contains(WINDOWS_SPLIT)) {
            return templatePath.substring(templatePath.lastIndexOf(WINDOWS_SPLIT) + 1);
        }
        return templatePath.substring(templatePath.lastIndexOf("/") + 1);
    }
}
调用
// PDFHeaderFooter headerFooter = new 
// PDFHeaderFooter();
// PDFKit kit = new PDFKit();
// kit.setHeaderFooterBuilder(headerFooter);
// fileName 导出文件名 data模板替换值 templatePath 模板路径
// kit.exportToFile(fileName, data,templatePath);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值