下载(导出)pdf模板文件(比如:审批单)

1. pom.xml引入包

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.6</version>
</dependency>
<dependency>
    <groupId>net.sf.jtidy</groupId>
    <artifactId>jtidy</artifactId>
    <version>r938</version>
</dependency>

2. 编写4个工具类,分别是FontProvider.java、FreeMarkToHtml.java、Html2Xhtml.java、XHtml2Pdf.java

  1. FontProvider.java
/**
 * 字体提供类, 更改 默认的字体
 */
public class FontProvider extends XMLWorkerFontProvider {

    public FontProvider() {
        super(null, null);
    }

    @Override
    public Font getFont(final String fontname, String encoding, float size, final int style) {
        String fntname = fontname;
        if (fntname == null) {
            fntname = "宋体";
        }
        return super.getFont(fntname, encoding, size, style);
    }
}
  1. FreeMarkToHtml.java
 /**
 * FreeMark处理类
 */
public class FreeMarkToHtml {

    /**
     * 通过路径 和文件名称后去魔板
     * @param templateFilePath
     * @param templateFileName
     * @return
     */
    public static Template getTemplate(String templateFilePath, String templateFileName) {
        try {
            Configuration cfg = new Configuration();
            cfg.setClassicCompatible(true);
            TemplateLoader templateLoader = new FileTemplateLoader(new File(templateFilePath));
            cfg.setTemplateLoader(templateLoader);
            return cfg.getTemplate(templateFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param templateFilePath
     * @param templateFileName 加载的模板文件名
     * @param replaceData
     * @param outFile  生成指定文件
     * @return 成功:返回文件名  失败:返回null
     */
    public static String freemarkToHtml(String templateFilePath, String templateFileName, Map<String, Object> replaceData, String outFile) {
        String path = null;
        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"))) {
            Template temp = getTemplate(templateFilePath, templateFileName);
            temp.setEncoding("UTF-8");
            temp.process(replaceData, out);
            path = outFile;
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
            path = null;
        }
        return path;
    }
}
  1. Html2Xhtml.java
/**
 * 将html 转换成为严格的XHTML
 */
public class Html2Xhtml {

    /**
     * 转化类
     * @param html  html文件输入路径(带文件名称)
     * @param xhtml xhtml文件输入路径(带文件名称)
     * @return
     */
    public static String html2Xhtml(String html, String xhtml) {

        String path = null;
        try (FileInputStream fin = new FileInputStream(html)) {
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            int data = -1;
            while ((data = fin.read()) != -1) {
                byteArrayOut.write(data);
            }
            fin.close();
            byte[] htmlFileData = byteArrayOut.toByteArray();

            byteArrayOut.close();

            ByteArrayInputStream tidyInput = new ByteArrayInputStream(htmlFileData);
            ByteArrayOutputStream tidyOut = new ByteArrayOutputStream();
            Tidy tidy = new Tidy();
            tidy.setInputEncoding("UTF-8");
            tidy.setOutputEncoding("UTF-8");
            tidy.setShowWarnings(false);
            tidy.setIndentContent(true);
            tidy.setSmartIndent(true);
            tidy.setIndentAttributes(false);
            tidy.setMakeClean(true);
            tidy.setQuiet(true);
            tidy.setWord2000(true);
            tidy.setXHTML(true);
            tidy.setErrout(new PrintWriter(System.out));
            tidy.parse(tidyInput, tidyOut);
            tidyInput.close();
            tidyOut.writeTo(new FileOutputStream(xhtml));
            tidyOut.flush();
            tidyOut.close();
            path = xhtml;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            path = null;
        }

        return path;
    }

}
  1. XHtml2Pdf.java
/**
 *  xhtml 转 pdf
 */
public class XHtml2Pdf {

    /**
     * 转化方法
     * @param html html文件输入路径(带文件名称)
     * @param pdf  pdf文件输出路径(带文件名称)
     */
    public static void XHtml2Pdf(String html, String pdf) throws FileNotFoundException, IOException, DocumentException, CssResolverException {
        int i = html.lastIndexOf(".html");
        String xhtml = null;
        xhtml = html.substring(0, i) + ".xhtml";
        xhtml = Html2Xhtml.html2Xhtml(html, xhtml);

        if (xhtml != null) {
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf));
            document.open();
            FontProvider fontProvider = new FontProvider();
            fontProvider.addFontSubstitute("lowagie", "garamond");
            fontProvider.setUseUnicode(true);
            // 使用我们的字体提供器,并将其设置为unicode字体样式
            CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
            HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
            htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
            CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
            Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));
            XMLWorker worker = new XMLWorker(pipeline, true);
            XMLParser p = new XMLParser(worker);

            File input = new File(xhtml);
            p.parse(new InputStreamReader(new FileInputStream(input), "UTF-8"));
            document.close();
        }
    }

}

3. 编写ExcelExportController.java类和ExcelExportService.java类

  1. ExcelExportController.java
@RestController
@RequestMapping("/excelExport")
public class ExcelExportController {


	@Autowired
	private ExcelExportService excelExportService;

    /**
     * 导出(下载)审批单
     * @return Response
     */
    @GetMapping("/exportApproveRecord")
    public void exportApproveRecord(ApproveQuery excelVo, HttpServletRequest request, HttpServletResponse response) {
        try {
            URLDecoder.decode(String.valueOf(excelVo), "UTF-8");
            excelExportService.exportApproveRecord(excelVo, request, response);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

}
  1. ExcelExportService.java
@Service
public class ExcelExportService {

    private final Logger logger = LoggerFactory.getLogger(ExcelExportService.class);

    //生产环境的下载路径(根据自己服务器的真实路径配置)
    String filePath = "/opt/deployments/BOOT-INF/classes/template/";
    //pdf文件名:审批单名字.pdf
    String pdfFileName = "审批单名字.pdf";
    //html模板文件路径(resources目录下)
    String templateFilePath = "template/approve_record.ftl";
    //html模板文件路名
    String templateFileName = "approve_record.html";

    /**
     * 导出(下载)审批单
     * @param excelVo
     * @param response
     */
    public void exportApproveRecord(ApproveQuery excelVo, HttpServletRequest request, HttpServletResponse response) {
        if (null == excelVo) {
            throw new BusinessException("导出打印审批单失败,请刷新界面重新操作!");
        }
        
        URL url = Thread.currentThread().getContextClassLoader().getResource("");
        //第1步:获取数据并创建文pdf文件
        Map<String, Object> tableData = new HashMap<>(3);
        tableData.put("data", new ArrayList<>());
       
        //第2步:模板转换
        FreeMarkToHtml.freemarkToHtml(Objects.requireNonNull(url).getPath(), templateFilePath, tableData, url.getPath() + templateFileName);
        try {
            XHtml2Pdf.XHtml2Pdf(url.getPath() + templateFileName, url.getPath() + pdfFileName);
        } catch (IOException | DocumentException | CssResolverException e) {
            e.printStackTrace();
        }

        //第3步:执行下载操作
        //filePath = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath();
        File file = new File(filePath + pdfFileName);
        try (
                InputStream is = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                BufferedInputStream bis = new BufferedInputStream(is)) {
            byte[] buff = new byte[1024];
            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e1) {
            throw new BusinessException("导出打印审批单失败,请刷新界面重新操作!");
        }
    }

}

4. 前端页面

  1. “导出”按钮
<Button icon={<DownloadOutlined />} type="primary" loading={exportApproveLoading} onClick={exportPrint}>
    导出审批单
</Button>
  1. “exportPrint”函数
/**
 * 导出打印审批单
 */
const exportPrint = async () => {
    setExportApproveLoading(true);
    //参数,没有可以不设置
    const url = `?params=1`;
    //url.replace去掉空格
    window.open(`/api/excelExport/exportApprove?excelVo=${encodeURI(url.replace(/\s/g, '')) }`, '_blank');
    setExportApproveLoading(false);
};

4. approve_record.ftl模板

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>审批单(pdf文件)</title>
</head>
<body>
<div class="main">
    <#if data??>
    	<!-- data为后端返回的数据 -->
        <div>${data}</div>
    </#if>
</div>
</body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值