React table row download file method summary

I. Introduction

When downloading a file, the response body returned by the background interface is in the file stream format. If the front end does not process it when receiving it, the file will not be downloaded correctly (the file may be opened directly, etc.).

Here, record the method of using file-saver to download files in the table row of react. ( 注意不同项目可能有差异,供参考)

Sample screenshot:
insert image description here

2. Use file-saver to download related codes in the react table row (take my project as an example)

1. First, there is a table tag in one of my js files AdvancedTable:

import AdvancedTable from '@/components/AdvancedTable';
……
          <AdvancedTable
            namespace="myPageModels"
            queryPara={queryPara}
            data={data}
            columns={this.getColumns()}
            rowSelection={rowSelection}
            loading={loading}
          />

Among them, namespace is related to the name of the table;
queryPara is related to the query parameters of the table, for example, which queryPara.page = 0; queryPara.sort = 'id,desc'; queryPara.size = 10;will be used by the frame when clicking to turn the page;
data is the table data, the format is [{"id":1,"name":"第一行"},{"id":2,"name":"第二行"}]like this, it is a JsonList array;
this.getColumns( ) is the method for displaying table row data, and the download button is implemented here, which will be described in detail later;

rowSelection is the configuration of whether the table row is allowed to be selected. It can be configured as single selection, multiple selection, no selection, etc., and the selected monitoring method can also be set;

loading is a flag indicating whether the loading of the table is complete. It can be controlled by the framework, or you can write your own logic, set it to false at the beginning, and then set it to true after a certain operation is successful, so that the table can be rotated in circles until the operation is successful. It shows that the loading is complete.

2.this.getColumns() is a method for displaying table row data, which has a download button. The sample is as follows:

import {Button, Divider, Icon, Collapse, Popconfirm, Modal, message, Switch, Drawer} from 'antd';


……

  getColumns = () => {
    const { dispatch } = this.props;

    const {
      pageSeriesModels: { isAdmin },
    } = this.props;

    const { nowPageValue } = this.state;

    const columns = [
      {……},
      
      {
        title: '下载',
        dataIndex: 'download',
        align: 'center',
        width: 100,
        render: (text, record) => (
          <Fragment>
            <Fragment>
              <a
                onClick={() =>
                  {
                    let fileSuffix = '';
                    try{
                    fileSuffix = record.documentName.substring(record.documentName.length-3,record.documentName.length).toLowerCase()
                    } catch(e){}
                    console.log("fileSuffix",fileSuffix)
                    if(fileSuffix === 'pdf'){
                      dispatch({
                        type: 'pageSeriesModels/downloadPdf',
                        paramFileId: record.id,
                        paramType: nowPageValue,
                        paramDocumentName: record.documentName,

                        //这个callback实际上写是写了,但是不知道为什么没有被调用
                        callback: (resp) => {
                          console.log(resp);
                          Modal.success({
                            centered: true,
                            content: '正在下载,请稍后',
                            okText: formatMessage({ id: 'global.ok' }),
                          });
                        },
                      })
                    }else{
					  message.error('文件格式错误,无法下载');
					}

                  }
                }
              >
                <Icon type="download" /> <FormattedMessage id="下载" />
              </a>
            </Fragment>
            
            {isAdmin ? <Divider type="vertical" /> : null }

            
            
          </Fragment>
        ),
      },
    ];
    return columns;
  };

The meaning of this paragraph is that a 下载button will be displayed in the form;
after clicking the download button, it will first judge whether the file name suffix is ​​pdf, if not pdf, a prompt message "The file format is wrong and cannot be downloaded" will pop up; if it is
pdf , the method will be called dispatchto execute another download method in js /downloadPdf, and the parameters passed in are ; where record.id is the id in the paramFileId: record.id, paramType: nowPageValue, paramDocumentName: record.documentName,table data , paramType is a type (for personal projects, the value is 1), and paramDocumentName is the same as dataThe reason is datathe file name in the table.

3. dispatchIn type: 'pageSeriesModels/downloadPdf', it will call another method in js, the sample is as follows:

import * as services from '@/services/api';

export default {
  namespace: 'pageSeriesModels',

  ……

  effects: {
    *downloadPdf({ paramFileId,paramType,paramDocumentName, callback }, { call, put }) {
      //const value = {};
      //value.fileId = paramFileId;
      //value.type = paramType;
      const response = yield call(services.down1, `/api/downloadPdf?fileId=${paramFileId}&type=${paramType}`, null, paramDocumentName);
      if (response) {
        if (callback) callback(response);
      }
    },

}

The usage of dispatch is not detailed here (you can read my previous article or Baidu);
this method means to call services.down1the method and pass in the input parameters;
if there is a return value response after execution, and there is a callback method callback (just now passed in when dispatch is called), the callback method is executed.

4. services.down1The method is in another js file written by myself (imported above), the sample is as follows:

import { stringify } from 'qs';
import { message } from 'antd';
import { saveAs } from 'file-saver';
import fetch from 'dva/fetch';

……

export async function down1(url, values, filename) {
  return fetch(`/commonHeadUrl${url}`, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/x-msdownload; charset=utf-8',
      Authorization: `Bearer ${sessionStorage.getItem('token')}`,
    },
  }).then(response => {
    if (response.status !== 200 && response.status !== 201) {
      message.error('出错了,请将功能路径告知管理员');
    } else {
      response.blob().then(blob => {
        if (blob.size === 0) {
          message.error('下载失败,请将功能路径告知管理员');
        } else {
          saveAs(blob, filename);
        }
      });
    }
  });
}

The meaning of this code is to set the post request and header parameters, and then request /commonHeadUrl/api/downloadPdf?fileId=${paramFileId}&type=${paramType}this address; (if the domain name is not explicitly written, the current domain name will be automatically included)
If the file stream is returned, use saveAsthe method to download, and the browser download will be realized up.

Among them, saveAsit is file-saverthe method in Li, if not, you can use the command to install:

npm install file-saver

If you don’t have other components, you can download them from Baidu first. If they are components of the framework, you can also npm i download them.

At this point, you can use file-saver to download files.

3. Remarks

1. In my vue project, I often use axiosrequests such as get and post

npm install axios

2. In my react project, use fetchsend get and post requests

(1)fetch:原生函数,不再使用 XmlHttpRequest 对象提交 ajax 请求。

(2)老版本浏览器可能不支持。

Guess you like

Origin blog.csdn.net/BHSZZY/article/details/130867696