Java操作html通过freemarker生成pdf

  1. 创建springboot项目,pom文件引入依赖如下:3
  2.          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
                <version>2.3.12.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.xhtmlrenderer</groupId>
                <artifactId>flying-saucer-pdf</artifactId>
                <version>9.0.9</version>
            </dependency>

3.创建工具类2个:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;

import java.io.File;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class CommunalTool {
    /**
     * 转换数据中的null为""(空串)
     *
     * @param obj       转换之前的数据
     * @param beanClass 转换之后的数据类型
     * @return 返回Object
     * @throws Exception
     */
    public static Object objectToData(Object obj, Class<?> beanClass) throws Exception {
        return JSONObject.parseObject(objectToString(obj), beanClass);
    }

    /**
     * Map中的null转换成""(空串)
     *
     * @param map 转换之前的数据
     * @return 返回 Map<String,Object>
     * @throws Exception
     */
    public static Map<String, Object> objectToMap(Map<String, Object> map) throws Exception {
        return JSONObject.parseObject(objectToString(map), Map.class);
    }

    /**
     * 把list中的null转换成""(空串)
     *
     * @param list 转换之前的数据
     * @return 返回list
     * @throws Exception
     */
    public static List objectToList(List list) throws Exception {
        return JSONObject.parseObject(objectToString(list), List.class);
    }

    // fistJson 的一个过滤器
    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    static DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    private static ValueFilter filter = new ValueFilter() {
        @Override
        public Object process(Object obj, String s, Object v) {
            if (v instanceof Date) {
                return simpleDateFormat.format(v);
            } else {
                if (v == null) {
                    return "";
                } else {
                    return v;
                }
            }
        }
    };

    /**
     * 将对象转换为json格式的字符串
     *
     * @param obj
     * @return String
     */
    public static String objectToString(Object obj) {
        // JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
        return JSON.toJSONString(obj, filter, SerializerFeature.WriteNonStringKeyAsString, SerializerFeature.WriteNullStringAsEmpty);
    }

    /**
     * 将图片转成base64 字符串
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64Picture(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        String result = new BASE64Encoder().encode(buffer);
        if (StringUtils.isNotBlank(result)) {
            result = "data:image/png;base64," + result;
        } else {
            result = null;
        }
        return result;
    }

    /**
     * 时间转换  yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getTransformationDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }

    /**
     * 时间转换  yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getTimeDate(Date date) {
        int minte = getMinute(date);
        minte = minte % 5;
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        Date afterDate = new Date(date.getTime() + 300000);
        System.out.println(sdf.format(afterDate));
        return "1";
    }

    /**
     * 功能描述:返回分
     *
     * @param date
     *            日期
     * @return 返回分钟
     */
    public static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 获取日期年份
     * @param date 日期
     * @return
     */
    public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
    public static String getTime(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_FULL);
        return df.format(date).substring(12, 16);
    }

}

 

import com.lowagie.text.pdf.BaseFont;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Map;
@Component
public class PdfHelper {



    /**
     * classpath路径
     */
    private String classpath = getClass().getResource("/").getPath();

    /**
     * 指定FreeMarker模板文件的位置
     */
    private String templatePath = "/templates";

    /**
     * freeMarker模板文件名称
     */
    private String templateFileName = "test.ftl";


    /**
     * 字体资源文件 存放路径
     */
    private String fontPath = "font/";

    /**
     * 字体   [宋体][simsun.ttc]   [黑体][simhei.ttf]
     */
    private String font = "simsun.ttc";

    /**
     * 指定编码
     */
    private String encoding = "UTF-8";


    /**
     * 生成pdf
     *
     * @param data 传入到freemarker模板里的数据
     * @param out  生成的pdf文件流
     */
    public void createPDF(Map<String, Object> data, OutputStream out, String templateName) throws Exception {
        // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
        Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        // 指定FreeMarker模板文件的位置
        ITextRenderer renderer = new ITextRenderer();
        /**
         * 要修改为字体下的路径
         */
        String simsun = System.getProperty("user.dir") + "\\src\\main\\resources\\font\\simsun.ttc";
        File fondFile = new File(simsun);
        if (!fondFile.exists()) {
            getFondPath();
        }
        renderer.getFontResolver().addFont(simsun, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        String templateString = getFileData("templates/" + templateName);
        stringLoader.putTemplate("myTemplate", templateString);
        cfg.setTemplateLoader(stringLoader);
        Template tpl = cfg.getTemplate("myTemplate", "utf-8");
        StringWriter writer = new StringWriter();

        // 把null转换成""
        Map<String, Object> dataMap = CommunalTool.objectToMap(data);
        // 将数据输出到html中
        tpl.process(data, writer);
        writer.flush();

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

        renderer.layout();
        renderer.createPDF(out, false);
        renderer.finishPDF();
        out.flush();
        out.close();

    }

    // 读取jar中的ftl模版文件
    private String getFileData(String path) {
        InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
        StringBuffer sb = new StringBuffer();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
            String s = null;
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            br.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取字体路径
     *
     * @return
     * @throws IOException
     */
    private String getFondPath() throws IOException {
        String fontPath = System.getProperty("user.dir");
        /**
         * 要修改为字体下路径
         */
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("font/simsun.ttc");
        //在根目录生成一个文件
        File targetFile = new File(fontPath + "/simsun.ttc");
        // //将流转成File格式
        FileUtils.copyInputStreamToFile(inputStream, targetFile);
        return fontPath;
    }

    public void setClasspath(String classpath) {
        this.classpath = classpath;
    }


    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }


    public void setTemplateFileName(String templateFileName) {
        this.templateFileName = templateFileName;
    }



    public void setFontPath(String fontPath) {
        this.fontPath = fontPath;
    }


    public void setFont(String font) {
        this.font = font;
    }


    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

}

准备html文件修改后缀名为ftl文件

 

在controller下调用API测试生成接口pdf文档

    //生成pdf流
    @PostMapping("/export")
    public void export(HttpServletResponse response,HttpServletRequest request) throws Exception {
        ServletOutputStream out = null;
        String userId = JwtUtils.parseToken(request.getHeader("token"));
        User user=userService.getById(Long.parseLong(userId));
        PdfHelper pdfHelper = new PdfHelper();
        Map<String,Object> map = new HashMap<>();
        map.put("name",user.getUserName());
        FileOutputStream outFile = new FileOutputStream(new File( "D:\\manager\\src\\main\\resources\\pdf\\"+user.getUserName()+"成绩证明"+".pdf"));
        pdfHelper.createPDF(map,outFile,"test.ftl");
//        try{
//            out = response.getOutputStream();
//
//            /** 导出pdf文件流 */
//            response.setCharacterEncoding("UTF-8");
//            response.setContentType("application/pdf");
//            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename="+ URLEncoder.encode("测试","UTF-8"));
//
//            FileInputStream inputStream = new FileInputStream(new File( "D:\\manager\\src\\main\\resources\\pdf\\1.pdf"));
//            // 读取文件流
//            int len = 0;
//            byte[] buffer = new byte[1024 * 10];
//            while ((len = inputStream.read(buffer)) != -1) {
//                out.write(buffer, 0, len);
//            }
//            out.close();
//        }catch (Exception e){
//            e.printStackTrace();
//        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值