This article is used to document the implementation of export functions in various business scenarios encountered in the project. Welcome to like the collection

1. Export the back – end link

This kind of export, I like most, the back end is more conscience, the front end is very easy. In this case, of course, there are two scenarios.

  • Link band domain name
if (res.code == 200) {
    window.location.href = res.data;
}
Copy the code
  • Links do not carry domain names

    The domain name is the domain name of the backend of the request, not the domain name of the front-end page. The project is usually used by multiple customers, so the domain name of the backend is usually configured by O&M. This is implemented in the project.

    Config. js file and config.js.example file are created in the public folder of static resources. The config.js file is uploaded to Git by chance. Update code will not overwrite the o&M configuration because it has been uploaded to Git. The config.js.example file is an example that tells operations how to configure it.

    Config.js has the same content as config.js.example

    Public /config.js */ window.apiConfig = {baseUrl: 'backend domain ',};Copy the code

    Then public/index.html introduces config.js

    <script> var script = document.createElement('script'); var num = Math.floor(Math.random() * 10000); script.src = 'config.js? a=' + num; document.getElementsByTagName('head')[0].appendChild(script); script = document.getElementById('scriptConfig'); script.parentNode.removeChild(script); script = null; </script>Copy the code

    This is the last way to use it

    if (res.code == 200) {
        window.location.href = window.apiConfig.baseUrl+res.data;
    }
    Copy the code

Second, the back end returns binary data export

  • First we need to configure AXIOS, because the default data type for the server response is JSON, which is changed to BLOB.
    Export function export(data){return service.get(' IP address ',{params:data, responseType:'blob'})}Copy the code
  • Then usenew Blob()To process binary data, generate a file, and use it againcreateObjectURL()After the link is created, it is automatically downloaded with the A link. Let’s wrap the method and hang it on the Vue prototype chain.
Const install = function (Vue, opts) {* binary data export processing * @ param blob binary stream * @ param name filename * / Vue. Prototype. ExportExcels = Const file = new blob ([blob], {type: 'application/vnd.ms-excel'}); function(blob,name){// type = new blob ([blob], {type: 'application/vnd.ms-excel'}); / / compatible with different browser URL object const URL = window. The URL | | window. WebkitURL | | window. MoxURL; Const downloadHref = url.createObjecturl (file); // create a tag and add attributes to it. Let downloadLink = document.createElement('a'); downloadLink.setAttribute('href', downloadHref); downloadLink.setAttribute('download', name); / / add a label to the document in the body. The body. The appendChild (downloadLink); // trigger the click of the a TAB to automatically download downloadlink.click (); / / download removed after the completion of a label document. Body. RemoveChild (downloadLink); RevokeObjectURL (downloadHref); } } export default{ install }Copy the code
  • Where the first argument to new Blob() is array, where each entry is a binary stream, and the second argument is an optional property, where the type attribute is the MIME type of the file, which is determined by the back end.

    Common MIME types are as follows

    suffix The name of the MIME
    *.csv text/csv
    *.doc application/msword
    *.dot application/msword
    *.xls application/vnd.ms-excel
    *.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

3. Add parameters to the address of the export interface to open the download directly

The above two scenarios require the server to first request the returned data and then process it before downloading it. In this scenario, add parameters to the address of the export interface to open the download directly, for example:

Window.location. href = 'export interface address '? user='lhy'&date='2020-05';Copy the code

The above request method is similar to the GET method, but when requesting the export interface with too many parameters, using the GET method will result in missing parameters. In this case, try to use the POST method request.

Because this scenario is directly open the export interface address download, it is not easy to use the POST method, so this time use HTML

tag and DOM form object to solve the problem.

We implement it by encapsulating a component.

<template>
    <form :action="action" :target="target" :method="method" ref="exports">
        <template v-if="data.length">
            <input type="hidden" autocomplete="off" v-for="(item,i) in data" :name="item.name" :value="item.value"/>
        </template>
        <input type="hidden" autocomplete="off" readonly name="token" :value="token"/>
    </form>
</template>
<script>
    export default {
        name: 'formExport',
        props: {
            action: {
                type: String,
                default: '',
            },
            target: {
                type: String,
                default: '_blank',
            },
            method: {
                type: String,
                default: 'post',
            },
            token:{
                type: String,
                default: '',
            },
            data: {
                type: Array,
                default() {
                    return [];
                }
            }
        },
        methods: {
            submit() {
                return new Promise((resoleve,reject) =>{
                    if (this.token) {
                        this.$refs.exports.submit();
                        resolv()
                    }else{
                        reject()
                    }
                }
            }
        }
    }
</script>
Copy the code

Component document

  • parameter
    parameter instructions type An optional value The default value
    action This parameter is mandatory. The address of the exported interface is mandatory String
    target Specifies where to open the export interface address String _blank: It opens in a new window

    _self: opens in the current window
    _blank
    method Request method String post/get post
    token Mandatory, authentication String
    data This parameter is mandatory and is passed to the server

    {name: parameter name,value: parameter value}
    String
  • methods
    The name of the event instructions The callback parameter
    submit Submit the form Promise object
  • The sample
    <template> <formExport ref="export" :action="exportData.url" :data="exportData.url" :token=" exportdata. token"></formExport> <el-button @click="handleExport"> Export </el-button> </template> <script> export Default {data(){return{exportData:{url:' export interface address ', data:{user:' LDS ', Page :1, pageSize:20, statTime:'2020-04', endTime:'2020-05' }, token:'12334f' } } }, components:{ formExport: () =>import('./formExport.vue') }, methods:{ handleExport(){ setTimeout(() => { this.$refs.export.submit(); }, 500); } } } </script>Copy the code

The backend only returns JSON data and the front-end generates Excel download

This is done using the XLSX and file-Saver plug-ins. Where XLSX is to generate Excel files, file-save is to save and download Excel files

  • Install XLSX and the file-Saver plug-in using NPM and run the command
npm install xlsx --save
npm install file-saver --save
Copy the code
  • Import Export2Excel. Js in the Servie folder, where you can encapsulate the methods in the XLSX and file-Saver plug-ins.

  • Let’s wrap the method and hang it on the Vue prototype chain

    • Parameter document
    parameter instructions type The default An optional value The sample
    header Table header data array [‘ Primary Customer ‘, ‘Application Customer ‘,’ Alipay Account ‘, ‘Withdrawal Amount ‘,’ Applicant ‘, ‘Application Time ‘]
    data Tabular data array [{}, {}]
    filename Excel file name string ‘excle1’
    opition Additional configuration object {}
    • Opition document
    parameter instructions type The default An optional value The sample
    filterVal Filtering table data array [‘id’,’name’]
    multiHeader Table header data except the last row of table header data, is two-dimensional data, not enough to complete with ”, only valid if bookType is XLSX or XLS. array [[‘ number ‘, ‘customer information’, ‘ ‘, ‘ ‘and’, ‘], [‘ and ‘customer name’, ‘withdrawal information’, ‘, ‘, ‘]]
    merges The rule for merging table headers is valid only if bookType is XLSX or XLS. array [‘A1:A3’, ‘B1:F1’, ‘B2:B3’, ‘C2:F2’]
    autoWidth Whether the table content is of adaptive width boolean true true/false
    bookType Generated file type string xlsx xlsx/xls/csv
Const install = function(Vue,opts){/** * json data to generate Excel and download @param header table data @param data table data @param filename Excel file name * @ param opition. Additional configuration * / Vue prototype. DownloadExcels = function (header, data, filename, opition) { let defaultOpition = { filterVal: [], multiHeader: [], merges: [], autoWidth: true, bookType: 'xlsx', } if (header && Object.prototype.toString.call(header) ! = '[object Array]') {throw new Error('header please pass Array '); } if (data && Object.prototype.toString.call(data) ! = '[object Array]') {throw new Error('data please pass Array '); } if (opition && Object.prototype.toString.call(opition) == '[object Object]') { defaultOpition = Object.assign({}, defaultOpition, opition); } if (Object.prototype.toString.call(defaultOpition.filterVal) ! = '[object Array]') {throw new Error('filterVal please pass Array '); } if (Object.prototype.toString.call(defaultOpition.multiHeader) ! = '[object Array]') {throw new Error('multiHeader '); } if (Object.prototype.toString.call(defaultOpition.merges) ! = '[object Array]') {throw new Error('merges please pass Array '); } const formatJson = function (filterVal, jsonData) { if (filterVal.length == 0) { return jsonData; } else { return jsonData.map(v => filterVal.map(j => v[j])); } } data = formatJson(defaultOpition.filterVal, data); If (data[0].length > header.length) {throw new Error(' The length of each item in data is greater than the length of the header '); } defaultOpition['data'] = data; defaultOpition['header'] = header; defaultOpition['filename'] = filename; import('./Export2Excel').then(res => { res.export_json_to_excel(defaultOpition); }) } } export default{ install }Copy the code
  • The sample

HandleExport () {const header = [' primary customer ', 'application customer ',' alipay account ', 'Withdrawal amount ',' applicant ', 'application time ']; const option = { bookType: 'xlsx', filterVal: ['firstCustomName', 'custom_name', 'withdrawals_bank', 'withdrawals_amount', 'do_username', 'add_time'], multiHeader: [[' number ', 'customer information', ' ', ' 'and', '], [' and 'customer name', 'withdrawal information', ', ', ']], merges: } this.downloadExcels(header, this.tableData, 'audit record ', option)},Copy the code

5. Export by PDF

This export is suitable for visual data scenarios

  • Introduce PDF generation script jspdf.js in index.html.
  • Html2canvas.js is a script that introduces screenshots in index.html.
  • Let’s wrap the method and hang it on the Vue prototype chain
Const install = function(Vue,opts){* to export the page as a PDF file * @param ID ID of the DOM area to generate the PDF file * @param fileName Name of the exported file * @param height Prototype. ExportPDF = function(id, fileName, height = 80){//html2canvas only truncates the viewable area of the DOM. Set the viewing area of the dom big solution to export problem of view of the document. The getElementById (id). OwnerDocument defaultView. InnerHeight = document.getElementById(id).scrollHeight + height; Html2canvas (document.getelementById (id), {scale: 2,// Scale up resolution (2= double).dpi: // Go to a specified DPI (points per inch),// Background: "# FFF ", // Set the background to white (the default is black) onRendered: function (canvas) { let contentWidth = canvas.width; let contentHeight = canvas.height; // a PDF page displays the canvas height generated by the HTML page; // let pageHeight = contentWidth / 592.28 * 841.89; // Don't generate PDF HTML page height let leftHeight = contentHeight; // PDF page offset let position = 0; ImgWidth = 595.28; // Canvas image width in PDF generated by HTML page Let imgHeight = 592.28 / contentWidth * contentHeight; Let pageData = canvas.toDataURL('image/jpeg', 1.0); let pdf = new jsPDF('', 'pt', 'a4'); // There are two heights to distinguish, one is the actual height of the HTML page, and the page height of the generated PDF (841.89). If (leftHeight < pageHeight) {PDF. AddImage (pageData, 'JPEG', 0, 0, imgWidth, imgHeight); } else { while (leftHeight > 0) { pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight); leftHeight -= pageHeight; The position - = 841.89; // Avoid adding a blank page if (leftHeight > 0) {pdf.addPage(); } } } pdf.save(fileName); } ) } } export default{ install }Copy the code