后端导出PDF文件(付前端实现代码)

JAVA后端导出PDF文件

文章目录

  • JAVA后端导出PDF文件
  • 前言
  • 一、前端代码
  • 二、使用步骤
    • 1. ftl模板
    • 2.后端代码
      • 2.1 核心接口代码
      • 2.2 本地方法 HtmlToPdf.htmlToPdf()
    • 3.测试


前言

效果图:
后端导出PDF文件(付前端实现代码)_第1张图片

一、前端代码

// 直接用href请求后端地址即可
window.location.href = http://localhost:8989/exportPdf;

二、使用步骤

1. ftl模板

注意:贴出的接口代码,读取的ftl模板的路径是,src\main\resources\templates\free.ftl

<#-- 如果值为null/空,则设置为空值 -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Freemarkertitle>
    <style type="text/css">
        #all {
            width: 600px;
        <#-- 使文档在pdf页面居中 --> margin: auto;
        }

        table {
            width: 100%;
            height: auto;
        <#-- @@提醒@@:此处必须指定字体,不然不识别中文  --> font-family: SimSun;
            text-align: center;
        <#-- table中单元格自动换行 --> table-layout: fixed;
            word-wrap: break-word;
        }

        tr td {
            padding: 2px;
            font-size: 10px;
            height: 20px;
        }

        tr th {
            padding: 2px;
            font-weight: bold;
            font-size: 10px;
            height: 20px;
        }
    style>
head>
<body>
<div id="all">
    <table border="1" cellspacing="0" cellpadding="0" align="center">
        <tr>
            <th colspan="5">${title}th>
        tr>
        <tr>
            <#-- 动态获取params的大小size -->
            <th rowspan="${params?size+1}">基本信息th>
            <td>姓名td>
            <td>电话td>
            <td>昵称td>
            <td>邮箱td>
        tr>
        <#list params as param>
            <tr>
                <td>${param.name}td>
                <td>${param.phone}td>
                <td>${param.nickname}td>
                <td>${param.email}td>
            tr>
        #list>
    table>
div>
body>
html>

2.后端代码

依赖:

 <dependency>
      <groupId>org.xhtmlrenderergroupId>
      <artifactId>flying-saucer-pdf-itext5artifactId>
      <version>9.0.3version>
  dependency>
  
  <dependency>
        <groupId>org.jsoupgroupId>
        <artifactId>jsoupartifactId>
        <version>1.13.1version>
  dependency>
  
  <dependency>
      <groupId>org.freemarkergroupId>
      <artifactId>freemarkerartifactId>
      <version>2.3.30version>
  dependency>
      
  <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-webartifactId>
  dependency>
  
 <dependency>
     <groupId>org.projectlombokgroupId>
     <artifactId>lombokartifactId>
     <version>${lombok.version}version>
 dependency>
 
   <dependency>
        <groupId>cn.hutoolgroupId>
        <artifactId>hutool-allartifactId>
        <version>5.6.0version>
    dependency>

2.1 核心接口代码

package com.example.export;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 导出pdf
 *
 */
@Slf4j
@RestController
public class ExportPdf {


    @GetMapping("/exportPdf")
    public void exportPdf(HttpServletResponse response) {
        // ========== pdf处理方式 ===========
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", "赵小刚");
        map1.put("phone", "15673890987");
        map1.put("nickname", "红孩儿");
        map1.put("email", "[email protected]");

        Map<String, Object> map2 = new HashMap<>();
        map2.put("name", "赵小刚");
        map2.put("phone", "15673890987");
        map2.put("nickname", "红孩儿");
        map2.put("email", "[email protected]");
        List<Map<String, Object>> stuffList = Arrays.asList(map1,map2);

        Map<String, Object> stuffMap = new HashMap<>();
        stuffMap.put("params", stuffList);
        stuffMap.put("title", "测试PDF模板");


        File pdfFile = FileUtil.file("test.pdf");
        try (OutputStream os = new FileOutputStream(pdfFile);) {
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
            // 如果填充值中与模板不匹配,或者为null值,则默认此值为空;
            cfg.setClassicCompatible(true);
            // 模板路径加载方式:基于类路径,即在src\main\resources\templates包下的ftl模板
            cfg.setClassForTemplateLoading(this.getClass(),"/templates");
            Template template = cfg.getTemplate( "pdf.ftl");
            Writer writer = new StringWriter();
            template.process(stuffMap, writer);

            // 对pdf资料进行创建
            HtmlToPdf.htmlToPdf(writer.toString(),os);
            byte[] dataByte = FileUtil.readBytes(pdfFile);

            response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(dataByte.length));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s"
                    , URLEncoder.encode("pdf测试.pdf", "UTF-8")));
            IoUtil.write(response.getOutputStream(), Boolean.TRUE, dataByte);

        } catch (Exception e) {
            log.error("导出贷后检查表失败, 详情:{}", e.getMessage());
        } finally {
            // 删除项目classes/目录下生成的临时文件
            if (pdfFile.exists()) {
                FileUtil.del(pdfFile);
            }
        }


    }

}

2.2 本地方法 HtmlToPdf.htmlToPdf()

package com.example.export;

import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.pdf.BaseFont;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.OutputStream;

 /**
     * 将HTML转成PD格式的文件。html文件的格式比较严格
     * @param htmlText  html内容
     * @param os   pdf存储文件输出流, 需要调用方关闭流
     * @throws Exception
     */
    public static void htmlToPdf(String htmlText, OutputStream os) throws Exception {
        //  没有闭合标签,故删掉
        htmlText = htmlText.replace("", StrUtil.EMPTY);
        Document document = Jsoup.parse(htmlText);
        /*手动为一些标签添加闭合*/
        Elements meta = document.getElementsByTag("meta");
        String html = document.html();
        for (Element link : meta) {
            String s = link.outerHtml();
            String s1 = s.replace("/>", ">");
            html = html.replace(s, s1 + "");
        }
        Elements link1 = document.getElementsByTag("link");
        for (Element link : link1) {
            String s = link.outerHtml();
            String s1 = s.replace("/>", ">");
            html = html.replace(s, s1 + "");

        }
        html = html.replaceAll("
"
, "
"
); html = html.replaceAll(" ", " "); ITextRenderer renderer = new ITextRenderer(); renderer.setDocumentFromString(html); // 解决中文支持, 注意本地和生产必须有此字体文件 ITextFontResolver fontResolver = renderer.getFontResolver(); String currentSystem = System.getProperty("os.name").toLowerCase(); if("linux".equals(currentSystem)){ fontResolver.addFont("/usr/share/fonts/chinese/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); }else{ fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } renderer.layout(); renderer.createPDF(os); }

3.测试

启动项目,使用浏览器请求:http://localhost:8989/exportPdf
即可实现导出pdf测试文件

(本文完!转载需说明出处!)

你可能感兴趣的:(Java文件操作,java,html)