SpringBoot+Vue+mybatis生成pdf文件(表头跟页码,适应上传linux服务器后的操作)

SpringBoot+Vue+mybatis生成pdf文件(表头跟页码,适应上传linux服务器后的操作)

为什么使用后端去生成

现在前端vue是有一套生成pdf的依赖,很简单,但是生成的也没办法满足太多功能,例如表头页码,已经复制粘贴等问题

说明

本章有两个方法分别是生成两个模板合成一起的pdf文件,一个是单独一个pdf文件

依赖

	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>itextpdf</artifactId>
		<version>5.5.13</version> <!--(or higher)-->
	</dependency>

	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>itext-asian</artifactId>
		<version>5.2.0</version>
	</dependency>
	<dependency>
		<groupId>com.itextpdf.tool</groupId>
		<artifactId>xmlworker</artifactId>
		<version>5.4.1</version>
	</dependency>

后端目录

控制器
在这里插入图片描述

生成的模板位置
在这里插入图片描述

控制器代码

package org.jeecg.modules.drainage.controller;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfPTable;
import org.jeecg.modules.drainage.service.ISensorService;
import org.jeecg.modules.drainage.vo.SensorAndSensorWaterLevel;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.util.PDFMergerUtility;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "pdf接口")
@RestController
@RequestMapping("/pdf")
public class PdfController {
    @Autowired
    private ISensorService sensorService;

    private static final String classpath = PdfController.class.getClassLoader().getResource("").getPath();

    String filePath = classpath + "static/templateFCss.pdf";

    private static final String DEST = "templateFCss.pdf";
    private static final String DESTS = "fmr4s.pdf";
    private static final String RAINDESTS = "rainfall.pdf";
    private static final String HTML = "templateFCss.html";
    private static final String FHTML = "fmr4.html";
    private static final String RAINHTML = "rain.html";

    private static Configuration freemarkerCfg = null;

    static {
        freemarkerCfg =new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        freemarkerCfg.setTemplateLoader(new ClassTemplateLoader(PdfController.class,"/pdfTemplate/"));

        //freemarker的範本目錄
//        try {
//            freemarkerCfg.setDirectoryForTemplateLoading(new File(classpath));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }
    @ApiOperation(value = "導出一个模板pdf文件")
    @GetMapping("/pdfRainExport")
    public void pdfRainExport(HttpServletResponse response, String searchInput, String startDate, String endDate ) throws IOException, DocumentException {
        Map<String,Object> data = new HashMap<String,Object>();
		
		//mybatis查詢根據自己去查詢就好了
		
        List<SensorAndSensorWaterLevel> findSensor=  sensorService.findSensor(searchInput,null,null,null,startDate,endDate);

        data.put("findSensor", findSensor);
        PdfPTable table = new PdfPTable(2);
        
        String content =freeMarkerRender(data,RAINHTML);

        createPdf(content,RAINDESTS);

        //===============主要下載程式碼======================
        /**
         * 下載
         */
        String savePath = null;
        FileInputStream in = null;
        OutputStream out = null;
        BufferedOutputStream bos = null;
        //獲取文件名
        savePath = RAINDESTS;
        String filename = savePath.substring(savePath.lastIndexOf("/")+1);
        filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
//                    response.setContentType("application/pdf");
        String downloadpath = savePath;
        response.setContentType("application/pdf");
        //設置響應頭
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        //讀取下載文件保存文件流
        in= new FileInputStream(downloadpath);
        //創建輸出流
        out= response.getOutputStream();
        bos = new BufferedOutputStream(out);
        //緩存區
        byte buffer[] = new byte[1024];
        int len = 0;
        //循環内容到緩存區
        while((len = in.read(buffer)) > 0){
            bos.write(buffer, 0, len);
        }
        bos.flush();
        in.close();
        bos.close();
        //刪除臨時文件
        File deleteFile=new File(savePath);
        deleteFile.delete();
    }

    @ApiOperation(value = "導出两个模板合成的pdf文件")
    @GetMapping("/pdfFmrs4Export")
    public void projectExport( HttpServletResponse response ) throws IOException, DocumentException {
        System.out.println(classpath);
        Map<String,Object> data = new HashMap<String,Object>();

        List<SensorAndSensorWaterLevel> findSensor=  sensorService.findSensor(null,null,null,null,null,null);

        data.put("findSensor", findSensor);
        PdfPTable table = new PdfPTable(2);
        String content =freeMarkerRender(data,HTML);
        String contents =freeMarkerRender(data,FHTML);
        //System.out.println(content);

        createPdf(contents,DESTS);
        createPdf(content,DEST);

        //pdf合并工具類
        PDFMergerUtility mergePdf = new PDFMergerUtility();
        //合并后生成的pdf文件名稱
        String destinationFileName ="fmrs4.pdf";
        // 合并后pdf存放路徑
        String bothPath =  "e://test";
        File file3 = new File(classpath);
        try{
            if(!file3.exists()){
                file3.mkdirs();
            }
        }catch(Exception e1){
            e1.printStackTrace();
        }
        mergePdf.addSource(DEST);
        mergePdf.addSource(DESTS);
        //設置合并pdf名稱
        mergePdf.setDestinationFileName(classpath + File.separator + destinationFileName);
        //合并pdf
        try {
            try {
                mergePdf.mergeDocuments();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (COSVisitorException e) {
            e.printStackTrace();
        }
        //===============主要下載代碼======================
        /**
         * 下載
         */
        String savePath = null;
        FileInputStream in = null;
        OutputStream out = null;
        BufferedOutputStream bos = null;
        //獲取文件名
        savePath = classpath+"fmrs4.pdf";
        String filename = savePath.substring(savePath.lastIndexOf("/")+1);
        filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
//                    response.setContentType("application/pdf");
        String downloadpath = savePath;
        response.setContentType("application/pdf");
        //設置響應頭
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        //讀取下載文件保存文件流
        in= new FileInputStream(downloadpath);
        //創建輸出流
        out= response.getOutputStream();
        bos = new BufferedOutputStream(out);
        //緩存區
        byte buffer[] = new byte[1024];
        int len = 0;
        //循環内容到緩存區
        while((len = in.read(buffer)) > 0){
            bos.write(buffer, 0, len);
        }
        bos.flush();
        in.close();
        bos.close();
        //刪除臨時文件
        File deleteFile=new File(savePath);
        deleteFile.delete();
    }


    /**
     * freemarker渲染html
     */
    public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
        Writer out = new StringWriter();
        try {
            // 獲取模板,設置編碼
            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;
    }
    public static void createPdf(String content,String dest) throws IOException, DocumentException {
        ITextRenderer render = new ITextRenderer();

        // 解析html生成pdf
        render.setDocumentFromString(content);
        render.layout();
        String path = System.getProperty("catalina.home");
        render.createPDF(new FileOutputStream(dest));
        render.finishPDF();
    }
    /**
     * File to 64bit Str
     *
     * @param file
     * @return
     */
    public static String fileToBase64Str(File file) {
        byte[] data = null;
        InputStream inputStream = null;
        if (file != null) {
            try {
                inputStream = new FileInputStream(file);
                data = new byte[inputStream.available()];
                inputStream.read(data);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return Base64.encodeBase64String(data);
        }
        return null;
    }
}

模板代码

這裏的話就只舉例一個模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <style>
        body{
            font-family:SimHei;
        }
        .color{
            color: green;
        }
        .pos{
            position:absolute;
            left:200px;
            top:5px;
            width: 200px;
            font-size: 10px;
        }
        .pageTable{
            margin-top:0.5in;
        }
        .page{
            margin-top:0.6in;
        }
        @media print {
            div.header-right {
                display: block;
                position: running(header-right);
            }

            img{page-break-inside:avoid;}
            table{page-break-inside:avoid;}
        }
        @page {
            size: 8.5in 11in;
            margin-top:1.53in;
            margin-left:0.25in;
            margin-right:0.25in;
            margin-bottom:0.6in;
            /*@bottom-center {
                content : "Page " counter(page) " of " counter(pages);
            };	 */
            @bottom-center {
                content: element(footer)
            }

            @top-center {content: element(header)}
        }
        #header {
            position:running(header);
            margin-top:0.52in;
        }
        #footer {
            position: running(footer);
        }

        #pages:before {
            content: counter(page);
        }

        #pages:after {
            content: counter(pages);
        }
        table {
            border-top: 1px solid #999;
            border-spacing: 0;
        }
        table td {
            border-bottom: 1px solid #999;
            border-right: 1px solid #999;
        }

    </style>
</head>
<body>
<div id ="header">
    <table class="tablefmr4" style="margin-top:15px;margin: 0 auto; table-layout:fixed; " width="93%" >
        <thead>
        <tr style="background:#15afcc;color: #fff">
            <td width="65" style="padding: 7px; border-left: 1px solid #999; word-break:break-all; word-wrap : break-word;">Distriot-Static ID</td>
            <td width="135" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Station Name</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Observed Water Level(mPD)</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">River Bank Level(mPD)</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Alert Level(mPD)</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Water Depth above Alert Level(m)</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Probable Affected Areas</td>
            <td width="55" style="padding: 7px; word-break:break-all; word-wrap : break-word;">Time of Date Record</td>
        </tr>
        </thead>
    </table>
</div>
<div id="footer">
    <div style="text-align: center; width: 100%;font-size: 15px;">Page <span id="pages"> of </span></div>
</div>
<div class="page">
    <table class="pageTable" style="margin: 0 auto; table-layout:fixed; " width="95%" >
        <tbody width="80%">
        <#list findSensor as u>
        <tr>
            <td width="65" style=" border-left: 1px solid #999; padding: 15px 10px 10px 10px; word-break:break-all; word-wrap : break-word;">${u.stationId!''}</td>
            <td width="135" style="padding: 10px;word-break:break-all; word-wrap : break-word;">${u.location!''}</td>
            <td width="55" style="padding: 10px;word-break:break-all; word-wrap : break-word;">${u.waterLevel!''}</td>
            <td width="55" style="padding: 10px;word-break:break-all; word-wrap : break-word;">${u.riverbankLevel!''}</td>
            <td width="55" style="padding: 10px;word-break:break-all; word-wrap : break-word;">${u.alarmLevel!''}</td>
            <td width="55" style="padding: 10px; word-break:break-all; word-wrap : break-word;">${(u.waterLevel-u.alarmLevel)!''}</td>
            <td width="55" style="padding: 10px; word-break:break-all; word-wrap : break-word;"></td>
            <td width="55" style="padding: 10px; word-break:break-all; word-wrap : break-word;">${u.updateTime?string('YYYY-MM-dd HH:mm:ss')!''}</td>
        </tr>
        </#list>
        </tbody>
    </table>
</div>


</body>
</html>

前端代碼

接口

// 导出pdf
export function pdfFmrs4Export(fileName) {
  return request({
    url: '/api/pdf/pdfFmrs4Export',
    method: 'get',
    responseType: 'arraybuffer',
    params:{
      fileName:fileName //文件名稱
    }
  }).then(response => {
    console.log(response);
    const elink = document.createElement("a");
    console.log(new Blob([response.data]));
    elink.href = window.URL.createObjectURL(new Blob([response], {type: `application/pdf;;charset-UTF-8`}));
    elink.style.display = 'none';
    elink.setAttribute('download',fileName);
    document.body.appendChild(elink);
    elink.click();
    URL.revokeObjectURL(elink.href); // 释放URL 对象
    document.body.removeChild(elink);
});
};

最終效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杰杰1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值