下载文件流

复制代码
// 通过后端接口拿到文件流
 export function getExport(url, parameter, method) {
   return request({
     url: url,
     method: method || 'post',
     data: method !== 'get' ? parameter : null,
     params: method === 'get' ? parameter : null,
     responseType: 'blob' // 这一行是关键,拿到blob数据类型的文件
   })
 }

转载链接:https://www.cnblogs.com/buluzombie/p/16735403.html
复制代码

下载xls文件:

复制代码
downloadFile.js

export let downloadFile = function (res, filename) {
  // 将blob对象转为一个URL
  let blobURL = window.URL.createObjectURL(res)
  // 创建一个a标签
  let tempLink = document.createElement('a')
  // 隐藏a标签
  tempLink.style.display = 'none'
  // 设置a标签的href属性为blob对象转化的URL
  tempLink.href = blobURL
  // 给a标签添加下载属性 decodeURI 解码
  tempLink.setAttribute('download', decodeURI(filename))
  if (typeof tempLink.download === 'undefined') {
    tempLink.setAttribute('target', '_blank')
  }
  // 将a标签添加到body当中
  document.body.appendChild(tempLink)
  // 启动下载
  tempLink.click()
  // 下载完毕删除a标签
  document.body.removeChild(tempLink)
  window.URL.revokeObjectURL(blobURL)
}
复制代码
复制代码
import { downloadFile } from "@/utils/downloadFile";

<el-button @click="exportFile">下载文件</el-button>

methords:{
       exportFile(){
                getExport(参数).then((res) => {
                     downloadFile(res,'名称'); 
               });
        }        
} 
复制代码

下载word文档:

复制代码

downloadFile.js

export function downloadWord(data, fileName, fileSuffix) {
  let fileTypeMime = '' // 文件 mime 类型,移动端必传,否则下载不成功;pc端可传可不传
  switch (fileSuffix) { // 获取后缀对应的 mime
    case 'png':
      fileTypeMime = 'image/png';
      break;
    case 'doc':
      fileTypeMime = 'application/msword';
      break;
    case 'docx':
      fileTypeMime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
      break;
    case 'jpg':
    case 'jpeg':
      fileTypeMime = 'image/jpeg';
      break;
    case 'gif':
      fileTypeMime = 'image/gif';
      break;
    case 'svg':
      fileTypeMime = 'image/svg+xml';
      break;
    case 'tif':
    case 'tiff':
      fileTypeMime = 'image/tiff';
      break;
    case 'txt':
      fileTypeMime = 'text/plain';
      break;
    case 'ppt':
      fileTypeMime = 'application/vnd.ms-powerpoint';
      break;
    case 'pptx':
      fileTypeMime = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
      break;
    case 'xls':
      fileTypeMime = 'application/vnd.ms-excel';
      break;
    case 'xlsx':
      fileTypeMime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      break;
    case 'zip':
      fileTypeMime = 'application/zip';
      break;
    case '7z':
      fileTypeMime = 'application/x-7z-compressed';
      break;
  }

  let blob = window.URL.createObjectURL(new Blob([data], {
    'type': fileTypeMime
  }))
  let link = document.createElement('a')
  link.style.display = 'none'
  link.href = blob
  link.setAttribute('download', fileName + fileSuffix)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link) //下载完成移除元素
  window.URL.revokeObjectURL(blob) //释放掉 blob 对象
}
复制代码
复制代码
import { downloadFile } from "@/utils/downloadFile";

<el-button @click="exportFile">下载文件</el-button>

methords:{
       exportFile(){
      getExport(参数).then((res) => { downloadWord(res, "名称", ".docx"); }); 
    } }
复制代码

 下载pdf文件:

npm install html2canvas -S;
npm install jspdf -S;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<strong>htmlPdf.js<br></strong>
 
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
 
export default {
  install(Vue, options) {
    // 不分页
    // Vue.prototype.getPdf = function () {
    //   let title = this.exportPDFtitle;
    //   html2Canvas(document.querySelector('#pdfDom'), {
    //     // allowTaint: true,
    //     useCORS: true,
    //     // scale: 2, // 提升画面质量,但是会增加文件大小
    //   }).then((canvas) => {
    //     const contentWidth = canvas.width
    //     const contentHeight = canvas.height
 
    //     /* 导出不分页处理 */
    //     const pageData = canvas.toDataURL('image/jpeg', 1.0)
 
    //     const pdfWidth = (contentWidth + 10) / 2 * 0.75
    //     const pdfHeight = (contentHeight + 200) / 2 * 0.75 // 500为底部留白
 
    //     const imgWidth = pdfWidth
    //     const imgHeight = (contentHeight / 2 * 0.75) // 内容图片这里不需要留白的距离
 
    //     const PDF = new JsPDF('', 'pt', [pdfWidth, pdfHeight, ])
    //     PDF.addImage(pageData, 'jpeg', 0, 0, imgWidth, imgHeight)
    //     PDF.save(title + '.pdf')
    //   })
    // }
    // 分页处理
    Vue.prototype.isSplit = function (nodes, index, pageHeight) {
        // 计算当前这块dom是否跨越了a4大小,以此分割
        if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
          return true;
        }
        return false;
      },
      Vue.prototype.uploadPdf = function () {
        let ST = document.documentElement.scrollTop || document.body.scrollTop;
        let SL = document.documentElement.scrollLeft || document.body.scrollLeft;
        document.documentElement.scrollTop = 0;
        document.documentElement.scrollLeft = 0;
        document.body.scrollTop = 0;
        document.body.scrollLeft = 0;
        //获取滚动条的位置并赋值为0,因为是el-dialog弹框,并且内容较多出现了纵向的滚动条,截图出来的效果只能截取到视图窗口显示的部分,超出窗口部分则无法生成。所以先将滚动条置顶
        const A4_WIDTH = 592.28;
        const A4_HEIGHT = 841.89;
        let imageWrapper = document.querySelector('#pdfDom') // 获取DOM
        let pageHeight = imageWrapper.scrollWidth / A4_WIDTH * A4_HEIGHT;
        let lableListID = imageWrapper.querySelectorAll("p");
        // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
        for (let i = 0; i < lableListID.length; i++) {
          let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight);
          if (this.isSplit(lableListID, i, multiple * pageHeight)) {
            let divParent = lableListID[i].parentNode; // 获取该div的父节点
            let newNode = document.createElement('div');
            newNode.className = 'emptyDiv';
            newNode.style.background = '#ffffff';
            let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight);
            //留白
            newNode.style.height = _H + 30 + 'px';
            newNode.style.width = '100%';
            let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
            // 判断兄弟节点是否存在
            if (next) {
              // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
              divParent.insertBefore(newNode, next);
            } else {
              // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
              divParent.appendChild(newNode);
            }
          }
        }
        //接下来开始截图
        this.$nextTick(() => {
          // nexttick可以保证要截图的部分全部执行完毕,具体用法自行百度...
          let title = this.exportPDFtitle;
          html2Canvas(imageWrapper, {
            allowTaint: true,
            // x: imageWrapper.getBoundingClientRect().left + 13, // 绘制的dom元素相对于视口的位置
            // y: imageWrapper.getBoundingClientRect().top,
            width: imageWrapper.offsetWidth - 15, // 因为多出的需要剪裁掉,
            height: imageWrapper.offsetHeight,
            backgroundColor: "#FFF", //一定要设置北京颜色,否则有的浏览器就会变花~,比如Edge
            useCORS: true,
            scale: 3, // 图片模糊
            dpi: 350, //z
          }).then((canvas) => {
            let pdf = new JsPDF('p', 'mm', 'a4'); //A4纸,纵向
            let ctx = canvas.getContext('2d'),
              a4w = 190,
              a4h = 270, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
              // imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4显示比例换算一页图像的像素高度
              imgHeight = a4h * canvas.width / a4w, //按A4显示比例换算一页图像的像素高度
              renderedHeight = 0;
            while (renderedHeight < canvas.height) {
              let page = document.createElement("canvas");
              page.width = canvas.width;
              page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
              //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
              page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
              pdf.addImage(page.toDataURL('image/jpeg', 0.2), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); //添加图像到页面,保留10mm边距
              renderedHeight += imgHeight;
              if (renderedHeight < canvas.height)
                pdf.addPage(); //如果后面还有内容,添加一个空页
            }
            // pdf.save('测试.pdf');
            pdf.save(title + ".pdf")
          })
        })
      }
  }
}
main.js
// 生成PDF import htmlPdf from '@/utils/htmlPdf'; Vue.use(htmlPdf);
复制代码
index.vue

 <!-- 生成PDF文件信息 -->
 <div
      ref="targetDom"
      id="pdfDom"
      class="pdfDom"
      v-show="pdfDomShow"
      style="width:90%;
      padding-left: 40px;
      padding-right: 40px;
      position: absolute;
      right: 3000px;"
      >
    <h1>基本信息</h1>
        <table border="1" cellspacing="0" cellpadding="0" class="table_class">
          <tr>
            <td>信息1</td>
            <td>aaa</td>
            <td>信息2</td>
            <td>bbb</td>
            <td>信息3</td>
            <td>ccc</td>
          </tr>
        </table>
</div>

<el-button @click="exportFile">下载文件</el-button>

methords:{
       exportFile(){
        this.$nextTick(() => {
              this.uploadPdf();
            });
        }        
} 
复制代码

 

posted @   挽你手  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示