1、背景

在项目需求中需要将角色信息打印出来,转化成pdf,常规的方法,前端就可以实现,但是当一个用户信息有几百条,几千条时怎么办?前端转化pdf依靠的是浏览器和电脑的性能,这时候就需要我们后台来处理了。

2、Itext

iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。
。。。。。。。。

不多说了直接怼代码

生成一个pdf的流程

springboot将pdf文件转化为图片 springboot根据模板导出pdf_spring


没多大用,看看熟悉熟悉生成过程,相当于io流那一套操作。

3、集成springboot

先做一个模板

先用word创建一个word文件

然后转换成pdf模板,然后将模板放到static静态文件包下,模板如下:

springboot将pdf文件转化为图片 springboot根据模板导出pdf_java_02

(1)、创建springboot项目
(2)、在pom.xml文件中添加如下依赖
<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
(3)、实体类
/**
 * 专业素养竞赛成绩
 */
@Entity
@Table(name = "bt_user_pro_compt")
@Data
public class UserProCompt implements Serializable {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id", insertable = false, nullable = false)
  private Long id;

  /**
   * 用户ID
   */
  @Column(name = "user_id", nullable = false)
  private String userId;

  /**
   * 等级

	0  无
	1  A
	2  B
	3  C
   */
  @Column(name = "degree", nullable = false)
  private Integer degree;

  @Column(name = "attachments", nullable = false)
  private String attachments;

  
}
(4)、DO层操作
package com.zhitu.posreview.repository;

import com.zhitu.posreview.entity.UserOtoc;
import com.zhitu.posreview.entity.UserProCompt;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import java.util.List;

public interface UserProComptRepository extends JpaRepository<UserProCompt, Long>, JpaSpecificationExecutor<UserProCompt> {

    List<UserProCompt> findAllByUserId(String userId);

  
}
(5)、service层
package com.zhitu.posreview.service;

import com.zhitu.posreview.entity.user.UserMessageList;

import javax.servlet.http.HttpServletResponse;

/**
 * ProhectName posreview
 * Description TODD
 * Author zhengchaorui
 * Data 2019/5/21 21:26
 * Version 1.0
 **/

public interface PdfService {

    /**
    * description:生成pdf(用户信息集成在一块)
    * param:
    * return
    */
    void generatePDFFileTwo(String userId,HttpServletResponse response) throws Exception;


}

实现类

@Override
    public void generatePDFFileTwo(String userId, HttpServletResponse response) throws Exception {

        if (userId == null && "".equals(userId)) {
            throw new PosreviewException(ResponseResultEnum.OPERATION_ERROR);
        }
        //pdf模板相对路径
        String pdfModelPath = PathUtils.getPDFModelPath();
        //pdf临时文件相对路径
        String pdfTempPath = PathUtils.getPDFTempPath();
        //pdf合并文件相对路径
        String pdfExportPath = PathUtils.getPDFExportPath();
        UserMessageList userMessageList = getUserMessageList(userId);
        List<String> stringAllList = new ArrayList<>();
        //循环遍历文件夹下的文件
        List<String> dirlist = PdfUtils.findDir(pdfModelPath + "");
        for (int a = 0; a < dirlist.size(); a++) {
            String path = dirlist.get(a);
            File file = new File(path);
            String fileName = file.getName();
            if (("专业素养竞赛成绩.pdf").equals(fileName)) {
                List<UserProCompt> userProComptList = userMessageList.getUserProComptList();
                if (userProComptList.size() != 0) {
                    String textFromPage = PdfUtils.readPdf(path);
                    for (UserProCompt proCompt : userProComptList) {
                        List<String> stringList = new ArrayList<>();
                        UserProCompt userProCompt = proCompt;
                        String s = userProCompt.toString();
                        Map<String, String> keyvalMaps = PdfUtils.ProcessField(s);
                        String degree = keyvalMaps.get("degree");
                        if (degree.equals("null")){
                            degree="0";
                        }
                        String degree1 = UserAttainmentLevelEnum.analysisString(Integer.valueOf(degree));
                        String tmpPage = textFromPage;
                        String strDegree = tmpPage.replaceAll("degree", degree1);
                        stringList.add(strDegree);
                        stringAllList.addAll(stringList);
                    }
                }
            }
(6)封装的工具类
package com.zhitu.posreview.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.zhitu.posreview.entity.bean.AttachmentData;
import com.zhitu.posreview.enums.user.UserTiptopEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName: posreview
 * @Package: com.zhitu.posreview.utils
 * @ClassName: PathUtils
 * @Author: zhengchaorui
 * @Description: 相对路径解析工具类
 * @Date: 2019/5/13 15:46
 * @Version: 1.0.0
 */
@Slf4j
public class PathUtils {

    public static String getRootPath() {
        //获取跟目录
        File file;
        String path = null;
        try {
            file = new File(ResourceUtils.getURL("classpath:").getPath());
            if(!file.exists()) {
                file = new File("");
            }
            path = file.getAbsolutePath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return path;
    }
    public static String getTempPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/temp/,则可以如下获取:
        File file = new File(rootPath,"static/temp/");
        if(!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }
        return file.getAbsolutePath();
    }
    public static String getModelPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/model/,则可以如下获取:
        File file = new File(rootPath,"static/model/");
        if(!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }
        return file.getAbsolutePath();
    }
    public static String getExportPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/export/,则可以如下获取:
        File file = new File(rootPath,"static/export/");
        if(!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }


    public static String getPDFTempPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/temp/,则可以如下获取:
        File file = new File(rootPath,"static/pdf/temp/");
        if(!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }
        return file.getAbsolutePath();
    }
    public static String getPDFModelPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/model/,则可以如下获取:
        File file = new File(rootPath,"static/pdf/model/");
        if(!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }
        return file.getAbsolutePath();
    }
    public static String getPDFExportPath() {
        String rootPath = getRootPath();
        //如果上传目录为/static/export/,则可以如下获取:
        File file = new File(rootPath,"static/pdf/export/");
        if(!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

}
package com.zhitu.posreview.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.util.PDFMergerUtility;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * ProhectName posreview
 * Description pdf工具类
 * Author zhengchaorui
 * Data 2019/5/21 21:58
 * Version 1.0
 **/
public class PdfUtils {


    /**
     * description 读取pdf文件,输出pdf模板
     * param:
     * return
     */
    public static String readPdf(String path) {
        String textFromPage = "";
        PdfReader reader = null;
        try {
            reader = new PdfReader(path);
            reader.getNumberOfPages();
            /* 模板对象 */
            textFromPage = PdfTextExtractor.getTextFromPage(reader, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return textFromPage;
    }

    /**
     * description: 处理返回值
     * param:
     * return
     */
    public static Map<String, String> ProcessField(String toString) {

        String s1 = StringUtils.substringAfter(toString, "(");
        String s2 = StringUtils.substringBefore(s1, ")");
        Map<String, String> keyvalMaps = new HashMap<>();
        String[] split = s2.split(", ");
        for (String split1 : split) {
            String[] split2 = split1.split("=");
            if (split2.length == 2) {
                keyvalMaps.put(split2[0], split2[1]);
            }
        }
        return keyvalMaps;
    }

    /**
     * description 循环遍历文件夹下的文件
     * param:
     * return
     *
     * @return
     */
    public static List<String> findDir(String path) {
        File dir = new File(path);
        File[] fileList = dir.listFiles();
        List<String> strList = new ArrayList<String>();
        for (File f : fileList) {
            if ((f.isFile())) {
                strList.add(f.getAbsolutePath());
            }
        }
        return strList;
    }

    //暂时不用
    public static boolean mergePdfFiles(String[] files, String newfile) throws Exception {
        boolean retValue = false;
        Document document = null;
        try {
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));
            document.open();
            for (int i = 0; i < files.length; i++) {

                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {

                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
            }
            retValue = true;
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return retValue;
    }


    private static String[] getFiles(String folder) throws IOException {
        File _folder = new File(folder);
        String[] filesInFolder;

        if(_folder.isDirectory()){
            filesInFolder = _folder.list();
            return filesInFolder;
        } else {
            throw new IOException("Path is not a directory");
        }
    }

    /**
     * description: 多个pdf合成一个pdf
     * param:
     * return
     */
    public static void mergePdf(String filePath,String savePath) throws IOException, COSVisitorException {

        //pdf合并工具
        PDFMergerUtility mergePdf = new PDFMergerUtility();
        String destinationFileName = "message.pdf";
        String[] filesInFolder = getFiles(filePath);
        for(int i = 0; i < filesInFolder.length; i++){
            //循环添加要合并的pdf存放的路径
            mergePdf.addSource(filePath + File.separator + filesInFolder[i]);
        }
        mergePdf.setDestinationFileName(savePath+ File.separator + destinationFileName);
        //合并pdf
        mergePdf.mergeDocuments();
    }

    /**
     * description:创建文件
     * param:
     * return
     */
    public static File createFile(File file){
        if(!file.exists()) {
            file = new File("");
        }
        return file;
    }

    /**
     * description 删除文件
     * param:
     * return
     */
    public static void delFile(String filePath) {
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            file.delete();
        }
    }

    /**
    * description 弹出文件
    * param:
    * return
    */
    public static void writerResponse(String fileName ,HttpServletResponse response, String exportPath) {
        try {
            response.setHeader("Content-Disposition", "attachment;filename="+ java.net.URLEncoder.encode(fileName, "UTF-8")+".pdf");
            response.setContentType("application/octet-stream");
            FileInputStream fis = new FileInputStream(exportPath);
            byte[] content = new byte[fis.available()];
            fis.read(content);
            fis.close();

            ServletOutputStream sos = response.getOutputStream();
            sos.write(content);
            sos.flush();
            sos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void getReflect(Object model) throws Exception{
        for (Field field : model.getClass().getDeclaredFields()) {
            field.setAccessible(true);

            Map<String, Object> map = new HashMap<>();
            map.put(field.getName(),field.get(model));

        }
    }

}
(7)、接口controller
package com.zhitu.posreview.controller;

import com.zhitu.posreview.vo.GetPage;
import com.zhitu.posreview.result.ResponseResult;
import com.zhitu.posreview.service.PdfService;
import com.zhitu.posreview.utils.ResponseResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * ProhectName posreview
 * Description 下载pdf功能
 * Author zhengchaorui
 * Data 2019/5/20 18:08
 * Version 1.0
 **/
@RestController
@CrossOrigin
@RequestMapping("/pdf")
public class PdfController {

    @Autowired
    private PdfService pdfService;

    @GetMapping("/makePdfFile")
    public void pdfFile(@RequestParam("id") String userId, HttpServletResponse response) throws Exception{
        pdfService.generatePDFFileTwo(userId,response);
    }

}

以上使用的技术springboot+JPA+mysql+iText