Spring Boot + VUE 实现PDF文件的打印预览

Spring Boot + VUE 实现PDF文件的打印预览

  • 导包
	<!-- pdf实现 -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.13</version>
    </dependency>

    <dependency>
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>5.5.13</version>
    </dependency>

  • 我是前端封装了post请求,所以这边请求类型直接使用的PostMapping。通过response返回文件流,前端解析直接加载到弹窗中
@PostMapping("/print")
    public void print(@RequestBody Cld cld, HttpServletResponse response) throws Exception {
        materialWeighService.print(cld, response);
    }
  • 制作添加PDF表单域,我的PDF模板文件存放在了项目目录中
    Spring Boot + VUE 实现PDF文件的打印预览_第1张图片
  • 下面是具体实现
@Override
    public void print(Cld cld, HttpServletResponse response) throws Exception {
		// 模板路径    
        String templatePath = "D:\\1\\2\\3\\pdfForm2.pdf";
       // 生成文件名
        String fileName = "resPDF";
        //指定相应类型(重要)
        response.setContentType("application/pdf;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode(fileName + ".pdf", "UTF-8"));
		// 准备添加数据
        Map<String, String> map = new HashMap<>();
        map.put("流水号", cld.get流水号());
        map.put("供应单位", cld.get供应单位());
        map.put("承运单位", cld.get承运单位());
        map.put("车牌号", cld.get车牌号());
        map.put("材料类别", cld.get进场分类());
        map.put("材料规格", cld.get规格());
        map.put("毛重", cld.get毛重() + "");
        map.put("皮重", cld.get皮重() + "");
        if (cld.getHan() == null) {
            map.put("含水率", "");
        } else {
            map.put("含水率", cld.getHan() + "");
        }
        String kz = cld.get暗扣重量() + cld.get扣杂重量() + "";
        map.put("扣除重量", kz);
        map.put("扣后净重", cld.get净重() + "");
        map.put("材料产地", cld.get生产单位());
        map.put("过磅员", cld.get验收人());
        map.put("过毛重日期时间", cld.get时间());
        map.put("回皮日期时间", cld.get回皮时间());
		
		
        PdfReader reader;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        PdfStamper stamper;

        try {
            os  = response.getOutputStream();
            // 读取PDF模板表单
            reader = new PdfReader(templatePath);
            baos = new ByteArrayOutputStream();
            // 根据表单生成新的PDF
            stamper = new PdfStamper(reader, baos);
            //获取PDF表单
            AcroFields formTexts = stamper.getAcroFields();
            // 设置字体(这里设置为系统字体,你也可以引入其他的字体),不设置很可能,中文无法显示。
            BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1",
                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            formTexts.addSubstitutionFont(bf);
            // 表单赋值
            for (Map.Entry<String, String> entry : map.entrySet()) {
                formTexts.setField(entry.getKey(), entry.getValue());
            }
			//设置为true为不可更改
            stamper.setFormFlattening(true);
            stamper.close();
            Document document = new Document();
            PdfCopy copy = new PdfCopy(document, os);
            document.open();
            PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(baos.toByteArray()), 1);
            copy.addPage(importedPage);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                baos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
  • VUE前端请求
    Spring Boot + VUE 实现PDF文件的打印预览_第2张图片
  • 其中service是封装的axios请求,其中要注意的是responseType参数,相应类型需指定为arraybuffer,其他类型如blob返回的文件流处理后PDF白屏,没有内容。

Spring Boot + VUE 实现PDF文件的打印预览_第3张图片

  • 响应头类型

Spring Boot + VUE 实现PDF文件的打印预览_第4张图片

  • 请求成功后response会返回如上的文件流
    Spring Boot + VUE 实现PDF文件的打印预览_第5张图片

  • 请求响应拦截器

  • 具体实现


<template slot-scope="scope">
 <el-button
  type="primary"
  size="mini"
  round
  icon="iconfont icon-a-ziyuan4"
  @click="print(scope.row)">打印el-button>
template>


<print-dialog
 :title="printDialog.title"
 :visible="printDialog.visible"
 :height="printDialog.height"
 :width="printDialog.width"
 @onClose="printClose()"
 @onConfirm="printConfirm()">
 <div slot="content">
   <pdf ref="pdf" :src="pdfUrl">pdf>
 div>
print-dialog>
  • 插件的使用
// 导入弹窗组件
import PrintDialog from '@/components/system/PrintDialog.vue'

//插件vue-pdf-signature
import pdf from "vue-pdf-signature";
import CMapReaderFactory from "vue-pdf-signature/src/CMapReaderFactory.js";

export default {
 components: {
   PrintDialog,
   pdf,
 },
 data() {
  return {
   printDialog: {
    title: 'pdf',
    visible: false,
    height: 800,
    width: 1670,
   },
   pdfUrl: '',
  }
 },
 methods: {
  // 打印
  async print(row) {
    let params = {
     // 组装参数
      pdf: row.组装参数,
      ...
      ...
    }
    let res = await materialWeighApi.print(params);
    this.getObjectUrl(res.data);
    this.printDialog.visible = true
	
	//也可实现下载功能
	// if (res) {
    //   constcontent = res.data; // 文件流
    //   const blob = new Blob([content], {
    //     type: 'application/octet-stream'
    //   });
    //   // 如果后端返回文件名
    //   const fileName = res.fileName;
    //   if ('download' in document.createElement('a')) {
    //     // 非IE下载
    //     const link = document.createElement('a');
    //     link.download = fileName;
    //     link.style.display = 'none';
    //     link.href = URL.createObjectURL(blob);
    //     console.log('ee', link.href);
    //     document.body.appendChild(link);
    //     link.click();
    //     URL.revokeObjectURL(link.href); // 释放URL 对象
    //     document.body.removeChild(link);
    //   }
    // }
  },
 },
 getObjectUrl(data) {
   let url= null;
   let file = new Blob([data], {type: "application/pdf" });
   if (window.createObjectURL != undefined) {
     url = window.createObjectURL(file);
   } else if (window.webkitURL != undefined) {
     // 兼容谷歌
     try {
       url = window.webkitURL.createObjectURL(file);
     } catch (error) {}
   } else if (window.URL != undefined) {
     // 兼容其他
     try {
       url = window.URL.createObjectURL(file);
     } catch (error) {}
   }
   //这里是重点,将处理的url使用CMapReaderFactory方法在进行处理
   url = pdf.createLoadingTask({ url: url, CMapReaderFactory });
   // 将转化后url赋值
   this.pdfUrl = url;
 },
 //dialog打印取消事件
 printClose() {
   this.printDialog.visible = false;
 },
 //dialog打印确认
 printConfirm() {
   this.$refs.pdf.print();
   this.printDialog.visible = false
 },
}
  • 参考
    后端
    前端
    前端

你可能感兴趣的:(spring,boot,vue.js,pdf)