下载 / 导出 / 文件流 / PDF

| 表单 post

// 创建一个提交和下载的公共方法,参数格式为action:'请求地址',method,'请求方式post/get',
// childInput:name:'后台参数key',value:'后台参数值'......]}
createExport(parameter){
    var form = document.createElement('form');
    form.setAttribute('action', parameter.action);
    form.setAttribute('method', 'post');
     // 循环参数列表设置form属性method
    for (var i = 0; i < parameter.childInput.length; i++) {
        var input = document.createElement('input');
        input.setAttribute('type', 'hidden');
        input.setAttribute('name', parameter.childInput[i].name);
        input.setAttribute('value', parameter.childInput[i].value);
        form.appendChild(input);
    }
    document.body.appendChild(form);
    // 使用form的document对象提交请求
    form.submit();
    document.body.removeChild(form);
}

// 调用
this.createExport({
    action : '/base/timeTrend/detailExport',
    childInput : [{
        name:'queryTime',
        value:'2018-02~2018-08'
    },{
        name:'queryType',
        value:1
    },{
        name:'exportAll',
        value:1
    }]
})

| get

window.open('路径 问号拼接传参');
// 或者
let a = document.createElement('a');
a.href = url;
a.download = "download";
document.body.appendChild(a);
a.click();
a.remove();

| 文件流转换base64

API.getWatermarkFile({
    "busiType": "credit",
    "isShowMD5": 1,
    "isLightOrShade": 1,
    "waterMarkContent": "222",
    "fileId": fileId,
    "platformCode": "pallas",
    "sensitiveDataMap": {
        "ip": returnCitySN['cip'],
        "time": this.getNowDate(1),
        "domain": "aries",
        "userId": "this.$userContent.userId",
        "userName": " this.$userContent.userName",
    }
}, { responseType: 'arraybuffer' }).then(res => {
    let imgUrl = 'data:image/png;base64,' + btoa(new Uint8Array(res).reduce((data, byte) => data + String.fromCharCode(byte), ""))
     this.imgUrl = imgUrl;
 })

| base64格式pdf在线预览、下载

// 在线预览
let win = window.open();
let imgUrl = "data:application/pdf;base64," + res.data.data.fileBase64;
win.document.write('&lt;iframe src="' + pdf + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen&gt;&lt;/iframe&gt;')

// 参考:https://majing.io/posts/10000000381103

// 文件流/base64 下载
aaaa(data) {
    // 完整base64字符串,不知道格式
    // function dataURLtoBlob: function(dataurl) {
    //     var arr = dataurl.split(','),
    //         mime = arr[0].match(/:(.*?);/)[1],
    //         bstr = atob(arr[1]),
    //         n = bstr.length,
    //         u8arr = new Uint8Array(n);
    //     while (n--) {
    //         u8arr[n] = bstr.charCodeAt(n);
    //     }
    //     return new Blob([u8arr], { type: mime });
    // }
    function dataURLtoBlob(dataurl) {
        var bstr = atob(dataurl)
        var n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: 'pdf' });
    }

    // res.data   就是后台返回的base64的 文件流
    let URL = dataURLtoBlob(data);
    var reader = new FileReader();
    reader.readAsDataURL(URL);
    reader.onload = function(e) {
        // 兼容IE
        if (window.navigator.msSaveOrOpenBlob) {
            var bstr = atob(e.target.result.split(",")[1]);
            var n = bstr.length;
            var u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            var blob = new Blob([u8arr]);
            window.navigator.msSaveOrOpenBlob(blob, '采购单.pdf');
        } else {
            // 转换完成,创建一个a标签用于下载
            var a = document.createElement('a');
            a.download = '采购单.pdf';
            a.href = e.target.result;
            a.setAttribute("id", "export")
            document.body.append(a); // 修复firefox中无法触发click
            a.click();
            document.getElementById("export").remove();
        }
    }
}

| PDF在线预览-PDFJS

  1. 下载整个pdf.js,下载地址:https://mozilla.github.io/pdf.js/。下载后解压,并复制到项目静态文件下[public/static]
  2. 请求后台数据,获取后台base64字段,并且保存到本地,然后跳转到刚刚添加的pdf.js项目里的viewer.html
    // 实例中viewer.html 路径,根目录public新建pdf文件夹,存放build和web [public/pdf] 
    // 备注:_imgUrl 与 viewerjs 中 变量注意一致
    sessionStorage.setItem("_imgUrl", res.data.data.fileBase64);
    window.open("/pdf/web/viewer.html");
    
  3. 打开pdfjs/web下的viewer.html文件,添加以下代码:
     <script type="text/javascript">
         var DEFAULT_URL = "";
         var pdfUrl = document.location.search.substring(1);
         if (null == pdfUrl || "" == pdfUrl) {
             // var BASE64_MARKER = ';base64,'; //声明文件流编码格式
             var preFileId = "";
             var pdfAsDataUri = sessionStorage.getItem("_imgUrl"); //这里就是pdf文件的base64码,我是通过session传递base64的
             var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
             DEFAULT_URL = pdfAsArray;
             //编码转换 
             function convertDataURIToBinary(dataURI) {
                 //[RFC2045]中有规定:Base64一行不能超过76字符,超过则添加回车换行符。因此需要把base64字段中的换行符,回车符给去掉。
                 // var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
                 // var newUrl = dataURI.substring(base64Index).replace(/[\n\r]/g, '');
                 var newUrl = dataURI.replace(/[\n\r]/g, '');
                 var raw = window.atob(newUrl); //这个方法在ie内核下无法正常解析。
                 var rawLength = raw.length;
                 //转换成pdf.js能直接解析的Uint8Array类型
                 var array = new Uint8Array(new ArrayBuffer(rawLength));
                 for (i = 0; i < rawLength; i++) {
                     array[i] = raw.charCodeAt(i) & 0xff;
                 }
                 return array;
             }
         }
     </script>
     // 注意新增代码要放在viewer.js引用之前
     <script src="viewer.js"></script>
    
  4. 修改 DEFAULT_URL

打开viewer.js,我这个版本直接搜索“DEFAULT_URL”会找不到(因为网上有个别帖子的版本是在viewer.js里搜到“DEFAULT_UR”并且要求注释的),但是通过寻找,发现我这个版本的“DEFAULT_URL”已经放在“defaultOptions”对象里面,找到这个参数后,修改“defaultUrl”的value为“DEFAULT_URL”

  defaultUrl: {
    value: DEFAULT_URL, // 新增
    // value: 'compressed.tracemonkey-pldi-09.pdf', // 注释此段
    kind: OptionKind.VIEWER
  }

打开viewer.js.map,搜索defaultUrl(或者compressed.tracemonkey-pldi-09.pdf),将compressed.tracemonkey-pldi-09.pdf 替换为DEFAULT_URL

  1. 解决pdf不显示电子签章的问题

pdf.worker.js 找到​如下代码注释

    // pdfjs 旧版
    if (this.data.fieldType === 'Sig') {
      warn('unimplemented annotation type: Widget signature');
      return false;
    }
    // pdfjs 新 版本v1.10.88 
    if (data.fieldType === 'Sig') {
       _this2.setFlags(_util.AnnotationFlag.HIDDEN);
    }