html模板转Pdf并导出

引入依赖

  <!-- https://mvnrepository.com/artifact/com.itextpdf/itext7-core -->
        <!--这是iText PDF库的核心组件,提供了一套API来创建、编辑和操作PDF文档-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.2.6</version>
            <type>pom</type>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.itextpdf/html2pdf -->
        <!--这个依赖是iText PDF的一个扩展,专门用于将HTML内容转换为PDF-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>html2pdf</artifactId>
            <version>4.0.5</version>
        </dependency>

        <!--Freemarker用于动态生成文本输出,如HTML、XML或其他任何格式的文本-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>

2个实体类

package com.jf.modules.model.vo;

import com.jf.modules.model.Assess;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author yu.chen1
 * @Description
 * @Data 2024/5/14 16:39
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConceptAllVo{
    /**
     * 场景描述
     */
    private String sceneDescribe;
    /**
     * 业务痛点
     */
    private String painPoints;
    /**
     * Ai能力
     */
    private String aiAbility;
    /**
     * 概念名称
     */
    private String conceptName;
    /**
     * AI代理的角色
     */
    private String who;
    /**
     *解决方案
     */
    private String solution;
    /**
     * 目标
     */
    private String value;
    /**
     * 评估
     */
    private Assess assess;

}


package com.jf.modules.model.vo;

import com.jf.modules.model.Assess;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author yu.chen1
 * @Description
 * @Data 2024/5/14 16:39
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConceptAllVo{
    /**
     * 场景描述
     */
    private String sceneDescribe;
    /**
     * 业务痛点
     */
    private String painPoints;
    /**
     * Ai能力
     */
    private String aiAbility;
    /**
     * 概念名称
     */
    private String conceptName;
    /**
     * AI代理的角色
     */
    private String who;
    /**
     *解决方案
     */
    private String solution;
    /**
     * 目标
     */
    private String value;
    /**
     * 评估
     */
    private Assess assess;

}

 util类

package com.jf.common.utils;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.layout.font.FontProvider;
import com.jf.modules.model.Assess;
import com.jf.modules.model.vo.ConceptAllVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author yu.chen1
 * @Description
 * @Data 2024/5/13 10:33
 **/
@Slf4j
public class FileTypeConvertUtil {
    /**
     * html转Pdf并导出
     * @param conceptAllVo
     * @param response
     * @return
     * @throws Exception
     */
    public static OutputStream downloadPdf(ConceptAllVo conceptAllVo,HttpServletResponse response) throws Exception {
        Assess assess = conceptAllVo.getAssess();
        //为html模板替换的数据(将${}转成传过来的数据)
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("sceneDescribe", conceptAllVo.getSceneDescribe());
        dataModel.put("painPoints", conceptAllVo.getPainPoints());
        dataModel.put("aiAbility", conceptAllVo.getAiAbility());
        dataModel.put("conceptName", conceptAllVo.getConceptName());
        dataModel.put("who", conceptAllVo.getWho());
        dataModel.put("solution", conceptAllVo.getSolution());
        dataModel.put("value", conceptAllVo.getValue());
        dataModel.put("totalPoints", assess.getTotalPoints());
        dataModel.put("costReduction", assess.getCostReduction());
        dataModel.put("revenueEnhancement", assess.getRevenueEnhancement());
        dataModel.put("topicInfluence", assess.getTopicInfluence());
        dataModel.put("inputControllability", assess.getInputControllability());
        dataModel.put("teamExcitement", assess.getTeamExcitement());
        dataModel.put("realizableDegree", assess.getRealizableDegree());

        // 设置响应字符编码为UTF-8
        response.setCharacterEncoding("UTF-8");
        // 设置响应内容类型
        response.setContentType("application/pdf");
        // 设置响应头
        String encodedFileName = null;
        try {
            encodedFileName = URLEncoder.encode("创意卡片.pdf", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
        //将html转换为pdf
        String htmlOutput = htmlToPdf(dataModel);
        //从response获取最终输出流
        OutputStream outputStream = response.getOutputStream();
        // ConverterProperties是Apache POI库中的一个类,主要用于处理Excel、Word等Microsoft Office文档中的数据类型转换。
        ConverterProperties properties = new ConverterProperties();
        //设置字体
        FontProvider fontProvider = new DefaultFontProvider(true, true, true);
        properties.setFontProvider(fontProvider);
        // 将html转换为pdf
        HtmlConverter.convertToPdf(htmlOutput, outputStream, properties);
        outputStream.close();
        return outputStream;
    }

    /**
     * 加载指定html模板并将数据填入html模板
     * @param dataModel
     * @return 
     * @throws TemplateException
     * @throws IOException
     */
    public static String htmlToPdf(Map dataModel) throws TemplateException, IOException {
        // 初始化配置对象,设置模板加载的类和路径
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
        cfg.setClassForTemplateLoading(FileTypeConvertUtil.class, "/");
        // 加载指定的模板文件
        Template template = cfg.getTemplate("test.html");
        // 使用StringWriter来收集模板处理后的结果
        StringWriter writer = new StringWriter();
        // 处理模板和数据模型,将结果写入到StringWriter中
        template.process(dataModel, writer);
        // 获取并返回处理后的HTML字符串
        return writer.toString();
    }

}

controller层

@RestController
@RequestMapping
public class AigcPromptWordsController {
     /**
     * 下载PDF
     * @param response
     * @param conceptAllVo
     */
    @PostMapping(value = "/downloadPDF")
    public void downloadPDF(HttpServletResponse response,@RequestBody ConceptAllVo conceptAllVo){
        try {
            FileTypeConvertUtil.downloadPdf(conceptAllVo,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

前端html模板

<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=UTF-8>
    <meta name=viewport content=width=device-width, initial-scale=1.0>
    <title>Download PDF</title>
    <style>
        body {
            font-family: '黑体', SimHei, STHeiti, sans-serif;
            line-height: 0.6;
        }
        .container {
            display: grid;
            grid-template-columns: 1fr 1fr; /* 创建两列 */
            grid-template-rows: auto auto auto; /* 创建三行 */
            gap: 10px; /* 设置单元格之间的间隔 */
        }
        .item {
            padding: 5px;
            margin-bottom: 5px;
        }

        h1, h2, h3 {
            color: #333;
        }
        p {
        color: #666;
        line-height: 1.6;
        word-wrap: break-word;
        overflow-wrap: break-word;
       }


    </style>
</head>
<body>
<h3>场景描述</h3>
<p>${sceneDescribe}</p>

<h3>面临的业务痛点</h3>
<p>${painPoints}</p>

<h3>使用AI能力</h3>
<p>${aiAbility}</p>

<h3>概念名称</h3>
<p>${conceptName}</p>

<h3>代理角色</h3>
<p>${who}</p>

<h3>解决方案</h3>
<p>${solution}</p>

<h3>目标</h3>
<p>${value}</p>
<div style="display: flex; align-items: center;">
    <h3 style="flex: 1 0 50%;">评论</h3>
    <p style="flex: 1 0 50%; text-align: left;">总分:${totalPoints}</p>
</div>
<div class=container>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;">对成本(人力/获客/运营等):${costReduction}</div>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;">对收益(流量/转化/效率)的提升:${revenueEnhancement}</div>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;"> 该概念可产生的话题影响力:${topicInfluence}</div>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;">投入(开发、迁移、培训等)是否可控:${inputControllability}</div>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;">团队对这个概念感到兴奋的程度:${teamExcitement}</div>
    <div class=item style="display:inline-block;  font-size: 16px; color: #666;">该概念可实现的程度:${realizableDegree}</div>
</div>
</body>
</html>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值