Spring Boot html 转pdf 批量下载,中文换行

  1. 先上效果图
  2. 所需字体和转换模板,下载地址https://download.csdn.net/download/weixin_42302549/20272350
  3. 所需jar包pom.xml
  • <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant</artifactId>
        <version>1.9.15</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.9</version>
    </dependency>
    
    <dependency>
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>5.5.9</version>
    </dependency>
    
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext-asian</artifactId>
        <version>5.2.0</version>
    </dependency>
    
    <dependency>
        <groupId>org.xhtmlrenderer</groupId>
        <artifactId>flying-saucer-pdf-itext5</artifactId>
        <version>9.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.31</version>
    </dependency>
  • 防止字体打包乱码
<resource>
    <!--打包该目录下的 application.yml -->
    <directory>src/main/resources</directory>
    <!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 -->
    <filtering>true</filtering>
    <excludes>
        <exclude>**/*.ttf</exclude>
        <exclude>**/*.ttc</exclude>
    </excludes>
</resource>
  • controller
  • package com.11.web.models.assess.controller;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.itextpdf.text.DocumentException;
    import com.jeoho.common.config.JeohoConfig;
    import com.jeoho.common.core.controller.BaseController;
    import com.jeoho.common.utils.DateUtils;
    import com.jeoho.common.utils.StringUtils;
    import com.jeoho.web.common.util.PDFUtil;
    import com.jeoho.web.models.assess.domain.TbAssessPublishDto;
    import com.jeoho.web.models.assess.service.ITbAssessPublishService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    /**
     * @ProjectName: jeoho$
     * @Package: com.jeoho.web.models.assess.controller$
     * @ClassName: PdfDownloadController$
     * @Description: 考核批量下载
     * @Author: lzy
     * @CreateDate: 2021/7/14$ 9:36$
     * @Version: 1.0
     */
    @RestController
    @RequestMapping("/assess/pdf")
    public class PdfDownloadController extends BaseController {
    
        @Autowired
        private ITbAssessPublishService tbAssessPublishService;
    
        @RequestMapping(value = "/download",method =  RequestMethod.GET)
        public void pdfExport( String ids, HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException {
    
            String[] split = ids.split(",");
            List<Long> collect = Arrays.stream(split)
                    .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            //考核体系
            List<TbAssessPublishDto> asessPublishDtos = tbAssessPublishService.selectTbAssessPublishDtoDetails(collect);
            //用户数据
            List<TbAssessPublishDto> tbAssessPublishDtos1 = tbAssessPublishService.selectUserNameAndDeptNameByIds(collect);
            //组装数据
            JSONArray jsonArray = new JSONArray();
            String filePath =  "/file/test/print";
            //删除zip包
            File file=new File(filePath+ "/print.zip");
            if(file.exists()){
                file.delete();
            }
            String path = filePath;
            //删除本地zip以及残余pdf//删除完里面所有内容
            PDFUtil.delAllFile(path);
            for(int i=0;i<jsonArray.size();i++){
                JSONObject obj = jsonArray.getJSONObject(i);
                Map<String,Object> data = new HashMap<String,Object>();
                JSONObject assessPublish = JSONObject.parseObject(obj.getString("assessPublish"));
                data.put("assessPublish",assessPublish);
                data.put("targets",obj.get("targets"));
                String fileNmae = assessPublish.get("accessTitle")+"-"+assessPublish.getString("nickName");
                PDFUtil.pdfExport(data,filePath,fileNmae);
            }
            PDFUtil.zipDowload(filePath, request, response);
        }
    
    }
    
  • PDFUtil
package com.11.web.common.util;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;
import com.11.common.config.JeohoConfig;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang.StringUtils;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

/**
 * @ProjectName: jeoho$
 * @Package: com.jeoho.common.utils$
 * @ClassName: PdfUtil$
 * @Description: pdf 下载
 * @Author: lzy
 * @CreateDate: 2021/7/14$ 10:06$
 * @Version: 1.0
 */
public class PDFUtil {

    private volatile static Configuration configuration;
    static {
        if (configuration == null) {
            synchronized (PDFUtil.class) {
                if (configuration == null) {
                    configuration = new Configuration(Configuration.VERSION_2_3_31);
                }
            }
        }
    }

    /**
     * 删除上次生成的pdf
     * @param path
     * @return
     */
    public static   boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                //先删除文件夹里面的文件
                delAllFile(path + "/" + tempList[i]);
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 生成pdf 方法 pdfExport
     * @param map
     * @param filePath
     * @param id
     * @throws IOException
     */
    public static  void pdfExport(Map<String,Object> map, String filePath, String id)throws IOException {
        //模板
        String HTML = "print.ftl";
        //名称
        String resource = filePath + "/print/" + id +".pdf";
        String content = freeMarkerRender(map, HTML);
        createPdf(content, resource);
    }

    /**
     * 合并数据以及模板
     * @param map
     * @param htmlTmp
     * @return
     */
    public static  String freeMarkerRender(Map<String,Object> map, String htmlTmp) {
        Writer out = new StringWriter();
        try {
            // 获取模板,并设置编码方式
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            String path ="template";

            cfg.setClassForTemplateLoading(PDFUtil.class, "/");
            //cfg.setDirectoryForTemplateLoading(new File(templatePath));
            cfg.setDefaultEncoding("UTF-8");
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
            Template template = cfg.getTemplate("template/print.ftl", "UTF-8");
            // 合并数据模型与模板,//将合并后的数据和模板写入到流中,这里使用的字符流
            template.process(map, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 生成pdf
     * @param content
     * @param dest
     * @throws IOException
     */
    public static void createPdf(String content,String dest) throws IOException{

        File file = new File(dest);
        if (!file.exists())
        {
            if (!file.getParentFile().exists())
            {
                file.getParentFile().mkdirs();
            }
        }
        //建立数据输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        ITextRenderer render = new ITextRenderer();
        // 创建字体解析器
        ITextFontResolver fontResolver = render.getFontResolver();
        try{
            // 设置字体
            fontResolver.addFont("template/simsun.ttc",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            fontResolver.addFont("template/simsun.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        }catch(Exception e){
            e.printStackTrace();
        }
        // 解析html生成pdf
        render.setDocumentFromString(content);
        // 解决图片相对路径的问题
        render.layout();
        try {
            render.createPDF(fileOutputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    /**
     *zip下载
     * @param filePath
     * @param request
     * @param response
     * @throws IOException
     */
    public static  void zipDowload(String filePath, HttpServletRequest request, HttpServletResponse response) throws IOException{
        //打包文件的存放路径
        ZipByAnt zc = new  ZipByAnt (filePath+ "/print.zip");
        //需要打包的文件路径
        zc.compress(filePath+ "/print/");

        //开始下载
        String userAgent = request.getHeader("USER-AGENT");
        //判断浏览器代理并分别设置响应给浏览器的编码格式
        String finalFileName = null;
        String fileZip = "print.zip";
        //IE浏览器
        if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){
            finalFileName = URLEncoder.encode(fileZip,"UTF8");
            System.out.println("IE浏览器");
            //google,火狐浏览器
        }else if(StringUtils.contains(userAgent, "Mozilla")){
            finalFileName = new String(fileZip.getBytes(), "ISO8859-1");
        }else{
            其他浏览器
            finalFileName = URLEncoder.encode(fileZip,"UTF8");
        }
        response.reset();
        response.setContentType("application/x-octet-stream;charset=utf-8");
        //下载文件的名称
        response.setHeader("Content-Disposition" ,"attachment;filename=\"" +finalFileName+ "\"");

        ServletOutputStream servletOutputStream = null;
        try {
            servletOutputStream = response.getOutputStream();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        DataOutputStream temps = new DataOutputStream(servletOutputStream);
        //下载文件路径
        DataInputStream in = new DataInputStream(
                new FileInputStream(JeohoConfig.getProfile()+"/print/"+finalFileName));
        byte[] b = new byte[4096];
        try {
            while ( (in.read(b)) != -1) {
                temps.write(b);
            }
            temps.flush();
            response.getOutputStream().flush();
            if(response.getOutputStream()!=null) {
                response.getOutputStream().close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(temps!=null) {
                temps.close();
            }
            if(in!=null){
                in.close();
            }
            servletOutputStream.close();
        }
    }
}
package com.jeoho.web.common.util;

/**
 * @ProjectName: jeoho$
 * @Package: com.jeoho.web.common.util$
 * @ClassName: ZipCompressorByAnt$
 * @Description:打包zip
 * @Author: lzy
 * @CreateDate: 2021/7/14$ 10:26$
 * @Version: 1.0
 */
import java.io.File;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;

public class ZipByAnt {
    private File zipFile;

    public ZipByAnt (String pathName) {
        zipFile = new File(pathName);
    }

    public void compress(String srcPathName) {
        File srcdir = new File(srcPathName);
        if (!srcdir.exists()){
            throw new RuntimeException(srcPathName + "不存在!");
        }


        Project prj = new Project();
        Zip zip = new Zip();
        zip.setProject(prj);
        zip.setDestFile(zipFile);
        FileSet fileSet = new FileSet();
        fileSet.setProject(prj);
        fileSet.setDir(srcdir);
        //fileSet.setIncludes("**/*.java"); 包括哪些文件或文件夹 eg:zip.setIncludes("*.java");
        //fileSet.setExcludes(...); 排除哪些文件或文件夹
        zip.addFileset(fileSet);
        zip.execute();
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值