Vue implements the operation code of clicking a button to download a file (backend Java)

Vue implements the operation code of clicking a button to download a file (backend Java)

In the previous article, I introduced the function of Vue to download files by clicking a button. Today, I will continue the topic of Vue to download files by clicking a button.

In the recent project, there is a need to realize the requirement of clicking a button to download files. Vue is used on the front end because the files are of various types, such as pictures, PDF, word and so on. Here the backend can return the address of the file to the frontend, but after looking at various answers on the Internet, I feel that none of them are what I want.

Because we are not sure what type the file is, we should store the Content-Type of the file when saving it to the database. In this way, when it is retrieved from the database and returned to the front end, the Content-Type identifies the type of file and the front end can parse it.

1. Backend code

Here I will first write the backend interface and consider what the backend needs. Because the file information has been stored in the database in advance, we only need to pass in the primary key id to get the file information. After determining the parameters, you need to determine the return value type. ResponseEntity can be used here to return. ResponseEntity can return multiple information at a time, including status code, response header information, response content, etc.

Without further ado, let’s look at the code.

/**
 * Download attachment * @param attachmentId
 * @return
 */
public ResponseEntity<byte[]> download(Long attachmentId) {
    // Check if the attachment exists SysAttachment sysAttachment = sysAttachmentMapper.selectSysAttachmentById(attachmentId);
    if (StringUtils.isNull(sysAttachment)) {
        return null;
    }

    ByteArrayOutputStream bos = null;
    InputStream ins = null;
    try {
        String fileName = sysAttachment.getOrgFileName();
        String ossFileName = sysAttachment.getUrl();
        bos = new ByteArrayOutputStream();
        ins = OssUtils.getInstance().getObject(ossFileName).getObjectContent();
        // Get data from the stream int len ​​= 0;
        byte[] buf = new byte[256];
        while ((len = ins.read(buf, 0, 256)) > -1) {
            bos.write(buf, 0, len);
        }

        // Prevent Chinese garbled characters fileName = URLEncoder.encode(fileName, "utf-8");
        // Set response headers HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename=" + fileName);
        headers.add("Content-Type", sysAttachment.getContentType());
        // Set the response HttpStatus statusCode = HttpStatus.OK;
        ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bos.toByteArray(), headers, statusCode);
        return response;
    } catch (Exception e) {
        throw new CustomException("Download failed");
    finally
        try {
            if (ins != null) {
                ins.close();
            }
            if (bos != null) {
                bos.close();
            }
        } catch (Exception e) {
            throw new CustomException("Download failed");
        }
    }
}

Here, we take the URL of the file from the database, and then get the input stream of the file through Alibaba Cloud OSS. Then we output the file as binary, encapsulate it into ResponseEntity, and set the file type to Content-Type. At the same time, in order to prevent the file name from containing garbled Chinese characters, we set UTF-8 encoding. At this point, the backend interface is completed.

Based on the above information, when we save file information in the database, we should at least save the following fields: the URL of the file (usually you will be given one after uploading it to OSS), the type of file, the original file name, the file size, etc.

2. Front-end code

With the back-end interface, the next step is the front-end. Here you can encapsulate the file download method into a general method and mount it globally, and then use it directly where you need it.

We need to identify different files, so we need a key-value pair to represent different files.

const mimeMap = {
  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  xls: 'application/vnd.ms-excel',
  zip: 'application/zip',
  jpg: 'image/jpg',
  jpeg: 'image/jpeg',
  png: 'image/png',
  doc: 'application/msword',
  docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  ppt: 'application/vnd.ms-powerpoint',
  txt: 'text/plain',
  pdf: 'application/pdf'
}

You can continue to add more if necessary. The next step is to send a request. The return type here can be set to blob and sent directly using axios.

/**
 * Download attachment* @param path interface address* @param param request parameter*/
export function downloadAttachment(path, param) {
  var url = baseUrl + path + param
  axios({
    method: 'get',
    url: url,
    responseType: 'blob',
    headers: { 'Authorization': getToken() }
  }).then(res => {
    resolveBlob(res, res.data.type)
  })
}

The interface address and request parameters are passed in from the outside. A token is also required, otherwise cross-domain access will occur. After getting the data returned by the backend, you need to parse the binary file. Here, we define the resolveBlob method, which has two parameters: the return object and the file type. We have already put the file type into Content-Type in the backend, so we just use it here.

/**
 * Parse blob response content and download * @param {*} res blob response content * @param {String} mimeType MIME type */
export function resolveBlob(res, mimeType) {
  const aLink = document.createElement('a')
  var blob = new Blob([res.data], { type: mimeType })
  // Get filename from the response headers, and the file name set by backend response.setHeader("Content-disposition", "attachment; filename=xxxx.docx");
  var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
  var contentDisposition = decodeURI(res.headers['content-disposition'])
  var result = patt.exec(contentDisposition)
  var fileName = result[1]
  fileName = fileName.replace(/\"/g, '')
  aLink.href = URL.createObjectURL(blob)
  aLink.setAttribute('download', fileName) // Set the download file name document.body.appendChild(aLink)
  aLink.click()
  document.body.removeChild(aLink);
}

There is no need to explain this code in detail, the front-end experts will naturally understand it. OK, here the front-end and back-end codes are completed.

3. Use

It’s even easier to use. Mount it globally first

import { downloadAttachment } from "@/utils/download"
Vue.prototype.downloadAttac = downloadAttachment

Just call it directly where you use it

<el-button
    type="text"
    icon="el-icon-download"
    size="mini"
    @click="downloadAttachRow(scope.row.attachmentId)"
    ></el-button>

/** Download attachment */
downloadAttachRow(attachId) {
    this.$confirm('Are you sure you want to download the file?', "Warning", {
        confirmButtonText: "Confirm",
        cancelButtonText: "Cancel",
        type: "warning"
    }).then(() => {
        this.downloadAttac('/system/attachment/download/', attachId)
    }).then(() => {
        this.msgSuccess("Download successful")
    }).catch(() => {})
}

That's the end.

This concludes this article about Vue's operation code for clicking a button to download files (back-end Java). For more relevant Vue content about clicking a button to download files, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue implements the function of clicking a button to download files
  • Vue implements sample code for clicking a button to switch the background color
  • Vue click button to dynamically create and delete component functions
  • How to use Vue to directly download files and modify file names through the URL connection of Alibaba Cloud OSS
  • Vue implements the complete front-end and back-end code for downloading file streams

<<:  How to view and configure password expiration on Linux

>>:  Analysis of the Principle of MySQL Index Length Limit

Recommend

The iframe refresh method is more convenient

How to refresh iframe 1. To refresh, you can use j...

The difference and usage of LocalStorage and SessionStorage in vue

Table of contents What is LocalStorage What is Se...

VUE Getting Started Learning Event Handling

Table of contents 1. Function Binding 2. With par...

A graphic tutorial on how to install MySQL in Windows

Abstract: This article mainly explains how to ins...

10 ways to view compressed file contents in Linux (summary)

Generally speaking, when we view the contents of ...

mysql8.0 windows x64 zip package installation and configuration tutorial

MySQL 8 Windows version zip installation steps (d...

Several common methods of CSS equal height layout

Equal height layout Refers to the layout of child...

Native js to realize a simple snake game

This article shares the specific code of js to im...

Detailed explanation of Vue's props configuration

<template> <div class="demo"&g...

Native js to implement a simple calculator

This article example shares the specific code of ...

A summary of detailed insights on how to import CSS

The development history of CSS will not be introd...