1. 程式人生 > >SpringBoot(十五)_springboot實現預覽pdf

SpringBoot(十五)_springboot實現預覽pdf

最近,專案上要做個列印的東西,還要預覽。我想就直接生成pdf預覽,然後使用者選擇列印

於是,昨天找了找資料。一般用itext 進行轉pdf。於是我就用springboot試了試,程式碼比較簡單,現在只是簡單的一個實現。

整體流程如下

  • 1.獲取資料(比如從資料庫獲取資料)
  • 2.通過freemarker 渲染頁面
  • 3.將渲染的頁面進行轉換為pdf,放在本地
  • 4.讀取pdf,實現預覽

主要程式碼

pom檔案

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.13</version>
        </dependency>


        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
    </dependencies>

PdfController程式碼

package com.kevin.pdf_demo.controller;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: kevin
 * @Date: 2018/11/16
 */
@RestController
public class PdfController {
    @Value("${DEST}")
    private String dest;
    @Value("${HTML}")
    private String html;
    @Value("${FONT}")
    private String font;
    private static Configuration freemarkerCfg = null;


    @RequestMapping(value = "helloPdf")
    public void showPdf(HttpServletResponse response) throws IOException, DocumentException {
        //需要填充的資料
        Map<String, Object> data = new HashMap<>(16);
        data.put("name", "kevin");

        String content = freeMarkerRender(data,html);
        //建立pdf
        createPdf(content, dest);

        // 讀取pdf並預覽
        readPdf(response);

    }

    public  void createPdf(String content,String dest) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        // step 3
        document.open();
        // step 4
        XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontImp.register(font);
        XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                new ByteArrayInputStream(content.getBytes("UTF-8")), null, Charset.forName("UTF-8"), fontImp);
        // step 5
        document.close();

    }

    /**
     * freemarker渲染html
     */
    public  String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
        Writer out = new StringWriter();

        try {
            // 獲取模板,並設定編碼方式
            setFreemarkerCfg();
            Template template = freemarkerCfg.getTemplate(htmlTmp);
            template.setEncoding("UTF-8");
            //將合併後的資料和模板寫入到流中,這裡使用的字元流
            template.process(data, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 設定freemarkerCfg
     */
    private void setFreemarkerCfg() {
        freemarkerCfg = new Configuration();
        //freemarker的模板目錄
        try {
            freemarkerCfg.setDirectoryForTemplateLoading(new ClassPathResource("template").getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 讀取本地pdf,這裡設定的是預覽
     */
    private void readPdf(HttpServletResponse response) {
        response.reset();
        response.setContentType("application/pdf");
        try {
            File file = new File(dest);
            FileInputStream fileInputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
            response.setHeader("Content-Disposition",
                    "inline; filename= file");
            outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



}

執行效果

設定頭資訊使瀏覽器下載檔案或預覽

強制瀏覽器下載

response.setHeader("content-disposition", "attachment;filename=" + realName);

瀏覽器嘗試開啟,支援office online或瀏覽器預覽pdf功能

response.setHeader("content-disposition", "inline;filename=" + realName);

完整程式碼 : github

玩的開心!