后端接口返回文件流,前端实现docx/pdf/excel等类型文件的导出功能

后端接口返回文件流,前端实现docx/pdf/excel等类型文件的下载功能

最近遇到一个需求,在后端返回文件流后前端需要实现导出docx类型的文件。在网上查看了一些资料总结了两种比较常用的方法。

方法一:前端接收到后端返回的数据后将返回结果转换为Blob类型,再进行操作。

1、封装接口

注意:接口需要添加 responseType: “blob”,否则会出现文件下载后无法打开或者损坏的情况。

export function downloadFile(id) {
  return request({
    url: "/project/approval/getWord/" + id,
    responseType: "blob",
    method: "post",
  })
}

2、转换数据格式

导出word文件,需要在创建blob对象时传入第二个参数,并将type设置为“application/vnd.openxmlformats-officedocument.wordprocessingml.document”

    handleDownload() {
      downloadPromise(this.ids[0]).then((res) => {
          let blob = new Blob([res], {
            type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
          });
          let objectUrl = URL.createObjectURL(blob);
          let link = document.createElement("a");
          let fname = "文件名称";
          link.href = objectUrl;
          link.setAttribute("download", fname);
          document.body.appendChild(link);
          link.click();
        })
        .catch(() => {
          this.$modal.msgWarning("文件下载出错!");
        });
    },

方法二:封装download方法(修改若依前端导出文件方法)

1、封装download方法

//该方法需要接受四个参数url:后端请求地址,params:请求参数,filename文件名称,contentType:content-type类型。
export function download(url, params, filename, config, contentType) {
  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    //这里可以根据导出文件的类型来传相应的Content-Type值
    headers: { 'Content-Type': contentType ? contentType : 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isBlob = blobValidate(data);
    if (isBlob) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      Message.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误,请联系管理员!')
    downloadLoadingInstance.close();
  })
}

2、调用download方法

    handleDownload() {
      this.download(
        "/project/approval/getWord/" + this.ids[0],
        //没有请求参数则传空对象
        {},
        //文件名称可以自行设置
        `type_${new Date().getTime()}.docx`,
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      );
    },

相关资料

在网上查找了一些关于 content-type 的编码格式以及responseType。

.doc     application/msword
.docx   application/vnd.openxmlformats-officedocument.wordprocessingml.document
.rtf       application/rtf
.xls     application/vnd.ms-excel application/x-excel
.xlsx    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.ppt     application/vnd.ms-powerpoint
.pptx    application/vnd.openxmlformats-officedocument.presentationml.presentation
.pps     application/vnd.ms-powerpoint
.ppsx   application/vnd.openxmlformats-officedocument.presentationml.slideshow
.pdf     application/pdf
.swf    application/x-shockwave-flash
.dll      application/x-msdownload
.exe    application/octet-stream
.msi    application/octet-stream
.chm    application/octet-stream
.cab    application/octet-stream
.ocx    application/octet-stream
.rar     application/octet-stream
.tar     application/x-tar
.tgz    application/x-compressed
.zip    application/x-zip-compressed
.z       application/x-compress
.wav   audio/wav
.wma   audio/x-ms-wma
.wmv   video/x-ms-wmv
.mp3 .mp2 .mpe .mpeg .mpg     audio/mpeg
.rm     application/vnd.rn-realmedia
.mid .midi .rmi     audio/mid
.bmp     image/bmp
.gif     image/gif
.png    image/png
.tif .tiff    image/tiff
.jpe .jpeg .jpg     image/jpeg
.txt      text/plain
.xml     text/xml
.html     text/html
.css      text/css
.js        text/javascript
.mht .mhtml   message/rfc822

""  responseType 设为空字符串与设置为"text"相同,默认类型
"text"  返回的是包含在 DOMString 对象中的文本。
"document"  返回的是一个 HTML Document 或 XML XMLDocument
"arraybuffer"  返回的是一个包含二进制数据的 JavaScript ArrayBuffer 
"blob"  返回的是一个包含二进制数据的 Blob 对象
"json"  返回的是一个 JavaScript 对象 。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。
"ms-stream"  返回的是下载流的一部分 ;此响应类型仅允许下载请求,并且仅受Internet Explorer支持

总结

使用第一种方法时遇到的坑,没有在接口api设置responseType: “blob”,导致文件下载成功后无法打开。最后,在前端开发过程中经常会遇到文件导出的需求,在这里总结一下用到过的方法以便在下次使用时可以直接复用。

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,使用 xdocreport 实现docx 文件转为 pdf ,然后将生成的 pdf 文件作为返回前端的示例代码如下: ```java @WebServlet("/docx-to-pdf") public class DocxToPdfServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 读取 docx 文件 String docxFilePath = "path/to/docx/file"; FileInputStream docxInputStream = new FileInputStream(new File(docxFilePath)); // 转换为 pdf IXDocReport report = XDocReportRegistry.getRegistry().loadReport(docxInputStream, TemplateEngineKind.Freemarker); Options options = Options.getTo(PdfViaIText5.class); ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); report.convert(options, pdfOutputStream); // 将 pdf 作为返回前端 response.setContentType("application/pdf"); response.setHeader("Content-disposition", "attachment;filename=output.pdf"); response.setContentLength(pdfOutputStream.size()); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(pdfOutputStream.toByteArray()); outputStream.flush(); outputStream.close(); } } ``` 这段代码中,我们先读取了系统中的 docx 文件,并使用 xdocreport 将其转换为 pdf。转换完成后,将生成的 pdf 文件作为直接返回前端。注意,响应头中的 Content-disposition 属性设置为 attachment,表示将 pdf 文件作为附件下载。如果不需要下载,可以设置为 inline。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值