SpringBoot下载freemarker转换的图片(高清不模糊)

一、背景

二、效果预览

三、项目

1.maven

2.FreemarkerUtil

3.Controller

4.freemarker文件

四、git项目地址


一、背景

需要根据不同的参数将freemarker的模板转成不同的图片返回给前端下载。

注意:想要图片不模糊,请调整如下参数

sharedContext.setDotsPerPixel(3);
sharedContext.setDPI(523);

二、效果预览

三、项目

1.maven

        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-core</artifactId>
            <version>9.1.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
            <version>2.2.9.RELEASE</version>
        </dependency>

2.FreemarkerUtil

package com.asyf.freemarkerdemo.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.swing.Java2DRenderer;

import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class FreemarkerUtil {

    private static Configuration config = null;

    static {
        String templatePath = FreemarkerUtil.class.getResource("/").getPath() + "templates";
        try {
            templatePath = ResourceUtils.getURL("classpath:").getPath() + "templates";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        log.info("ftl路径:" + templatePath);
        config = new Configuration(Configuration.VERSION_2_3_20);
        config.setDefaultEncoding("UTF-8");
        try {
            config.setClassForTemplateLoading(FreemarkerUtil.class, "/templates");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
        }
    }

    public static String generate(String template, Map params) throws Exception {
        Template tp = config.getTemplate(template);
        StringWriter stringWriter = new StringWriter();
        String htmlStr;
        try {
            tp.process(params, stringWriter);
            htmlStr = stringWriter.toString();
            stringWriter.flush();
        } finally {
            stringWriter.close();
        }
        return htmlStr;
    }


    public static BufferedImage html2Img(String html, int width, int height) throws Exception {
        byte[] bytes = html.getBytes();
        BufferedImage img;
        //转BufferedImage
        try (ByteArrayInputStream bin = new ByteArrayInputStream(bytes)) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(bin);
            Java2DRenderer renderer = new Java2DRenderer(document, width, height);
            SharedContext sharedContext = renderer.getSharedContext();
            sharedContext.setDotsPerPixel(3);
            sharedContext.setDPI(523);
            renderer.setBufferedImageType(4);
            Map map = new HashMap<>();//设置参数
            map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            map.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            map.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            map.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            map.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            map.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            map.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
            renderer.setRenderingHints(map);
            img = renderer.getImage();
        }
        return img;
    }

}

3.Controller

@RequestMapping(value = "test", method = RequestMethod.GET)
    public void html2ImageIo(HttpServletResponse response) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("name", "中文参数@123abc");
        String html = FreemarkerUtil.generate("test.ftl", param);
        BufferedImage bufferedImage = FreemarkerUtil.html2Img(html, 1500, -1);
        // 设置为png格式的文件
        response.setHeader("content-type", "image/png");
        //下载文件需要设置如下header
        //response.setHeader("content-type", "application/octet-stream");
        //response.setHeader("Content-Disposition", "attachment; filename=test.png");
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    }

4.freemarker文件

<html>
<head>
    <title>Welcome</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
        body,
        html,
        div,
        p {
            font-size: 14px;
            margin: 0px;
            padding: 0px;
            font-family: SimSun;
        }

        p {
            word-wrap: break-word;
            word-break: break-all;
        }
    </style>
</head>
<body>
<h1>freemarker模板</h1>
<h2>freemarker模板</h2>
<h3>freemarker模板</h3>
<h4>freemarker模板</h4>
<h5>freemarker模板</h5>
<span>中文参数:${name}</span>
<p>备注:${remark!'无'}</p>
<img src="http://n.sinaimg.cn/blog/transform/240/w650h390/20210728/99a6-d49c53639da1533f4f6f3968568f1ca1.jpg"/>
</body>
</html>

四、git项目地址

https://gitee.com/373616511/java-demo/tree/master/spring-demo/freemarker-demo

Guess you like

Origin blog.csdn.net/cs373616511/article/details/119541006