I had a problem with a file download at work. Scenario: Request a piece of binary data from the back end, download it at the click of a button. At the beginning of the download, the file could not be opened, or opened the garbled code. I finally solved the problem by consulting materials and learning. Here are the solutions and study notes.

To get the data

Send the request using AXIos. I’m using a POST request,

{
  url: 'your url'.method: 'post'./* Must be added otherwise it will be garbled */
  responseType: 'arraybuffer',}Copy the code
  • XMLHttpRequest.responseTypeIs an enumerated string value that specifies the data type in the response. (There are other values, you can choose according to actual needs)
  • The dutyarraybufferRepresents a JavaScript ArrayBuffer containing binary data.
  • The ArrayBuffer object is used to represent a generic, fixed-length buffer of raw binary data.

[responseType] [responseType] [responseType] [responseType] [responseType] [responseType] [responseType] [responseType] [responseType] [responseType]

Turn binary data into bloBs

Res is the raw binary data retrieved

const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
Copy the code
  • A Blob object represents an immutable, raw data-like file object. Its data can be read in text or binary format, or converted toReadableStreamFor data manipulation.
  • The constructorBlob(blobParts[, options])
    • blobPartsIs an Array made up of objects such as ArrayBuffer, ArrayBufferView, Blob, DOMString, etc., or a mixture of similar objects that will be put into the Blob. DOMStrings will be encoded to UTF-8.
    • optionsIs an optional BlobPropertyBag dictionary that may specify the following two properties:
      • typeThe default value is “”, which represents the MIME type of the array content to be put into the BLOB
      • endings, defaults to “transparent”, which specifies how strings containing line terminator \n are written. It is one of two values:
        • native, indicating that the end-of-line character is changed to a newline suitable for the host operating system file system
        • transparent, which means that the terminator saved in the BLOB is kept unchanged
  • Print the bloB object directly, and you get

This only shows the size and MIME type, if you want to see text:

const READER = new FileReader();
READER.addEventListener('loadend'.(e) = > {
  console.log(e.target.result);// Output the result here
  });
READER.readAsText(blob);
Copy the code

Ok!

  • MIME type, media type (often called Multipurpose Internet Mail Extensions or MIME type) is a standard used to represent the nature and format of a document, file, or byte stream.
    • This time, I only used Excel. If you need to use something else, you can check it on the Internet. The following one is.csvThe type of file
    { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8" }
    Copy the code

The download file

Download the blob using the Filer-Saver, and the blob is the bloB object handled in the previous step. What I’m going to download this time is an Excel file

import FileSaver from 'file-saver';
FileSaver.saveAs(blob, 'filename.xlsx');
Copy the code

This step is a pure API call.

Add it up

  const getListAll = () = > {
    setExportLoading(true);
    getExcel({
      params: {
        ...queryParams,
      },
    }, { responseType: 'arraybuffer' }).then((res) = > {
      if (res) {
        const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
        FileSaver.saveAs(blob, 'filename.xlsx');
      }
    }).finally(() = > {
      setExportLoading(false);
    });
  };
Copy the code