WeChat applet generates Excel

WeChat applet generates Excel

1. Problem description

Recently, I have been looking for a way to generate Excel in the WeChat applet. The requirement is to generate an Excel file or open an Excel file based on a json data or object array. I searched online for a long time, but couldn't find a very effective solution. Finally, I made one myself, but the generation efficiency is still relatively low.

Second, the realization of ideas

There are two methods that I agree with. The first is to use api to implement. If you have a server, then everything is fine. Just pass the data to the server, then the server generates the Excel file and returns the url of the file. Then download the file through wx.downloadFile and open the file with wx.openDocument. As for how to write an api that returns the url of an Excel file, there are too many methods.

But not everyone has a server, so there is an offline method to generate Excel files. My idea is that the Excel file itself is a compressed file, we only need to install the directory structure of Excel, create one by one file and folder, how to compress the file into xx.xlsx file.

As a result, Tencent Dog did not provide compression-related APIs. However, js has a ready-made jszip library that can be used. With jszip, we can start to implement it.

Third, the specific implementation

First download the jszip library, and then put the js files in dist into the utils directory under the applet.

Write a button in pages/index/index.wxml:

<!--index.wxml-->
<view class="container">
  <view>
      <button bindtap="createXLSX_zip">生成压缩包</button>
  </view>
</view>

Then import JSZip at the top of pages/index/index.js:

const JSZip = require("../../utils/jszip");

and write the response function:

createXLSX_zip() {
    
    
    const fs = wx.getFileSystemManager();
    let zip = new JSZip();
    const content = [
        {
    
    name: 'zack', age: 21, gender: 'male'},
        {
    
    name: 'alice', age: 20, gender: 'female'},
        {
    
    name: 'atom', age: 23, gender: 'male'},
        {
    
    name: 'rudy', age: 22, gender: 'male'},
    ]
    let contentXML = "";
    let idx = 0
    
    //按照Excel的规则,生成xml字符串
    let sheetData = `<row r="1" span="1:3">`
    let keys = Object.keys(content[0])
    for (let i = 0; i < keys.length; i++) {
    
    
        contentXML += `<si><t>${
      
      keys[i]}</t></si>`
        sheetData += `<c r="${
      
      String.fromCharCode(i + 'A'.charCodeAt())}1" t="s"><v>${
      
      idx}</v></c>`
        idx += 1
    }
    sheetData += '</row>'
    for (let i = 0; i < content.length; i++) {
    
    
        sheetData += `<row r="${
      
      i + 2}" span="1:3">`
        for (let j = 0; j < keys.length; j++) {
    
    
            contentXML += `<si><t>${
      
      content[i][keys[j]]}</t></si>`
            sheetData += `<c r="${
      
      String.fromCharCode(j + 'A'.charCodeAt())}${
      
      j + 2}" t="s"><v>${
      
      idx}</v></c>`
            idx += 1
        }
        sheetData += "</row>"
    }
    wx.showLoading({
    
    
        title: '正在生成',
    })
    zip.folder("docProps")
    zip.folder("xl")
    zip.folder("_rels")
    zip.file("[Content_Types].xml", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/><Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/></Types>')
    zip.file(`docProps/app.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Application>SheetJS</Application><HeadingPairs><vt:vector size="2" baseType="variant"><vt:variant><vt:lpstr>工作表</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="1" baseType="lpstr"><vt:lpstr>Sheet1</vt:lpstr></vt:vector></TitlesOfParts></Properties>')
    zip.file(`docProps/core.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><cp:lastModifiedBy>ivx</cp:lastModifiedBy><dcterms:created xsi:type="dcterms:W3CDTF">2022-07-11T07:23:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2022-07-11T07:25:43Z</dcterms:modified></cp:coreProperties>')
    zip.file(`docProps/custom.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="ICV"><vt:lpwstr>784038AB04864B7497D2D5CF431A9FF0</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="3" name="KSOProductBuildVer"><vt:lpwstr>2052-11.1.0.11830</vt:lpwstr></property></Properties>')
    zip.folder(`xl/theme`)
    zip.folder(`xl/worksheets`)
    zip.folder(`xl/_rels`)
    zip.file(`xl/sharedStrings.xml`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${
      
      keys.length * (content.length + 1)}" uniqueCount="${
      
      keys.length * (content.length + 1)}">${
      
      contentXML}</sst>`)
    zip.file(`xl/styles.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><numFmts count="4"><numFmt numFmtId="41" formatCode="_ * #,##0_ ;_ * \\-#,##0_ ;_ * &quot;-&quot;_ ;_ @_ "/><numFmt numFmtId="42" formatCode="_ &quot;¥&quot;* #,##0_ ;_ &quot;¥&quot;* \\-#,##0_ ;_ &quot;¥&quot;* &quot;-&quot;_ ;_ @_ "/><numFmt numFmtId="43" formatCode="_ * #,##0.00_ ;_ * \\-#,##0.00_ ;_ * &quot;-&quot;??_ ;_ @_ "/><numFmt numFmtId="44" formatCode="_ &quot;¥&quot;* #,##0.00_ ;_ &quot;¥&quot;* \\-#,##0.00_ ;_ &quot;¥&quot;* &quot;-&quot;??_ ;_ @_ "/></numFmts><fonts count="21"><font><sz val="12"/><color theme="1"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><sz val="11"/><color theme="1"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><sz val="11"/><color theme="1"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FF3F3F76"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FF9C0006"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color theme="0"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><u/><sz val="11"/><color rgb="FF0000FF"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><u/><sz val="11"/><color rgb="FF800080"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="11"/><color theme="3"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FFFF0000"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="18"/><color theme="3"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><i/><sz val="11"/><color rgb="FF7F7F7F"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="15"/><color theme="3"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><b/><sz val="13"/><color theme="3"/><name val="宋体"/><charset val="134"/><scheme val="minor"/></font><font><b/><sz val="11"/><color rgb="FF3F3F3F"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="11"/><color rgb="FFFA7D00"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="11"/><color rgb="FFFFFFFF"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FFFA7D00"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><b/><sz val="11"/><color theme="1"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FF006100"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FF9C6500"/><name val="宋体"/><charset val="0"/><scheme val="minor"/></font></fonts><fills count="33"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor theme="6" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFFFCC99"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="6" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFFFC7CE"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="6" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFFFFFCC"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="5" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="4" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="7" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFF2F2F2"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFA5A5A5"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="9" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="5"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFC6EFCE"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor rgb="FFFFEB9C"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="8" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="4"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="4" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="4" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="5" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="5" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="6"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="7"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="7" tint="0.799981688894314"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="7" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="8"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="8" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="8" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="9"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="9" tint="0.599993896298105"/><bgColor indexed="64"/></patternFill></fill><fill><patternFill patternType="solid"><fgColor theme="9" tint="0.399975585192419"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="9"><border><left/><right/><top/><bottom/><diagonal/></border><border><left style="thin"><color rgb="FF7F7F7F"/></left><right style="thin"><color rgb="FF7F7F7F"/></right><top style="thin"><color rgb="FF7F7F7F"/></top><bottom style="thin"><color rgb="FF7F7F7F"/></bottom><diagonal/></border><border><left style="thin"><color rgb="FFB2B2B2"/></left><right style="thin"><color rgb="FFB2B2B2"/></right><top style="thin"><color rgb="FFB2B2B2"/></top><bottom style="thin"><color rgb="FFB2B2B2"/></bottom><diagonal/></border><border><left/><right/><top/><bottom style="medium"><color theme="4"/></bottom><diagonal/></border><border><left/><right/><top/><bottom style="medium"><color theme="4" tint="0.499984740745262"/></bottom><diagonal/></border><border><left style="thin"><color rgb="FF3F3F3F"/></left><right style="thin"><color rgb="FF3F3F3F"/></right><top style="thin"><color rgb="FF3F3F3F"/></top><bottom style="thin"><color rgb="FF3F3F3F"/></bottom><diagonal/></border><border><left style="double"><color rgb="FF3F3F3F"/></left><right style="double"><color rgb="FF3F3F3F"/></right><top style="double"><color rgb="FF3F3F3F"/></top><bottom style="double"><color rgb="FF3F3F3F"/></bottom><diagonal/></border><border><left/><right/><top/><bottom style="double"><color rgb="FFFF8001"/></bottom><diagonal/></border><border><left/><right/><top style="thin"><color theme="4"/></top><bottom style="double"><color theme="4"/></bottom><diagonal/></border></borders><cellStyleXfs count="49"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/><xf numFmtId="42" fontId="1" fillId="0" borderId="0" applyFont="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="2" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="3" fillId="3" borderId="1" applyNumberFormat="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="44" fontId="1" fillId="0" borderId="0" applyFont="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="41" fontId="1" fillId="0" borderId="0" applyFont="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="4" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="4" fillId="5" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="43" fontId="1" fillId="0" borderId="0" applyFont="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="6" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="6" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="9" fontId="1" fillId="0" borderId="0" applyFont="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="7" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="1" fillId="7" borderId="2" applyNumberFormat="0" applyFont="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="8" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="8" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="9" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="10" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="11" fillId="0" borderId="0" applyNumberFormat="0" applyFill="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="12" fillId="0" borderId="3" applyNumberFormat="0" applyFill="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="13" fillId="0" borderId="3" applyNumberFormat="0" applyFill="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="9" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="8" fillId="0" borderId="4" applyNumberFormat="0" applyFill="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="10" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="14" fillId="11" borderId="5" applyNumberFormat="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="15" fillId="11" borderId="1" applyNumberFormat="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="16" fillId="12" borderId="6" applyNumberFormat="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="13" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="14" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="17" fillId="0" borderId="7" applyNumberFormat="0" applyFill="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="18" fillId="0" borderId="8" applyNumberFormat="0" applyFill="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="19" fillId="15" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="20" fillId="16" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="17" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="18" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="19" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="20" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="21" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="22" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="23" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="24" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="25" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="26" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="27" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="28" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="29" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="30" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="2" fillId="31" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf><xf numFmtId="0" fontId="5" fillId="32" borderId="0" applyNumberFormat="0" applyBorder="0" applyAlignment="0" applyProtection="0"><alignment vertical="center"/></xf></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/></cellXfs><cellStyles count="49"><cellStyle name="常规" xfId="0" builtinId="0"/><cellStyle name="货币[0]" xfId="1" builtinId="7"/><cellStyle name="20% - 强调文字颜色 3" xfId="2" builtinId="38"/><cellStyle name="输入" xfId="3" builtinId="20"/><cellStyle name="货币" xfId="4" builtinId="4"/><cellStyle name="千位分隔[0]" xfId="5" builtinId="6"/><cellStyle name="40% - 强调文字颜色 3" xfId="6" builtinId="39"/><cellStyle name="差" xfId="7" builtinId="27"/><cellStyle name="千位分隔" xfId="8" builtinId="3"/><cellStyle name="60% - 强调文字颜色 3" xfId="9" builtinId="40"/><cellStyle name="超链接" xfId="10" builtinId="8"/><cellStyle name="百分比" xfId="11" builtinId="5"/><cellStyle name="已访问的超链接" xfId="12" builtinId="9"/><cellStyle name="注释" xfId="13" builtinId="10"/><cellStyle name="60% - 强调文字颜色 2" xfId="14" builtinId="36"/><cellStyle name="标题 4" xfId="15" builtinId="19"/><cellStyle name="警告文本" xfId="16" builtinId="11"/><cellStyle name="标题" xfId="17" builtinId="15"/><cellStyle name="解释性文本" xfId="18" builtinId="53"/><cellStyle name="标题 1" xfId="19" builtinId="16"/><cellStyle name="标题 2" xfId="20" builtinId="17"/><cellStyle name="60% - 强调文字颜色 1" xfId="21" builtinId="32"/><cellStyle name="标题 3" xfId="22" builtinId="18"/><cellStyle name="60% - 强调文字颜色 4" xfId="23" builtinId="44"/><cellStyle name="输出" xfId="24" builtinId="21"/><cellStyle name="计算" xfId="25" builtinId="22"/><cellStyle name="检查单元格" xfId="26" builtinId="23"/><cellStyle name="20% - 强调文字颜色 6" xfId="27" builtinId="50"/><cellStyle name="强调文字颜色 2" xfId="28" builtinId="33"/><cellStyle name="链接单元格" xfId="29" builtinId="24"/><cellStyle name="汇总" xfId="30" builtinId="25"/><cellStyle name="好" xfId="31" builtinId="26"/><cellStyle name="适中" xfId="32" builtinId="28"/><cellStyle name="20% - 强调文字颜色 5" xfId="33" builtinId="46"/><cellStyle name="强调文字颜色 1" xfId="34" builtinId="29"/><cellStyle name="20% - 强调文字颜色 1" xfId="35" builtinId="30"/><cellStyle name="40% - 强调文字颜色 1" xfId="36" builtinId="31"/><cellStyle name="20% - 强调文字颜色 2" xfId="37" builtinId="34"/><cellStyle name="40% - 强调文字颜色 2" xfId="38" builtinId="35"/><cellStyle name="强调文字颜色 3" xfId="39" builtinId="37"/><cellStyle name="强调文字颜色 4" xfId="40" builtinId="41"/><cellStyle name="20% - 强调文字颜色 4" xfId="41" builtinId="42"/><cellStyle name="40% - 强调文字颜色 4" xfId="42" builtinId="43"/><cellStyle name="强调文字颜色 5" xfId="43" builtinId="45"/><cellStyle name="40% - 强调文字颜色 5" xfId="44" builtinId="47"/><cellStyle name="60% - 强调文字颜色 5" xfId="45" builtinId="48"/><cellStyle name="强调文字颜色 6" xfId="46" builtinId="49"/><cellStyle name="40% - 强调文字颜色 6" xfId="47" builtinId="51"/><cellStyle name="60% - 强调文字颜色 6" xfId="48" builtinId="52"/></cellStyles><tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/><extLst><ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"><x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/></ext></extLst></styleSheet>')
    zip.file(`xl/workbook.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><fileVersion appName="xl" lastEdited="3" lowestEdited="5" rupBuild="9302"/><workbookPr codeName="ThisWorkbook"/><bookViews><workbookView windowWidth="24225" windowHeight="11940"/></bookViews><sheets><sheet name="Sheet1" sheetId="1" r:id="rId1"/></sheets><calcPr calcId="144525"/></workbook>')
    zip.file(`xl/theme/theme1.xml`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F497D"/></a:dk2><a:lt2><a:srgbClr val="EEECE1"/></a:lt2><a:accent1><a:srgbClr val="4F81BD"/></a:accent1><a:accent2><a:srgbClr val="C0504D"/></a:accent2><a:accent3><a:srgbClr val="9BBB59"/></a:accent3><a:accent4><a:srgbClr val="8064A2"/></a:accent4><a:accent5><a:srgbClr val="4BACC6"/></a:accent5><a:accent6><a:srgbClr val="F79646"/></a:accent6><a:hlink><a:srgbClr val="0000FF"/></a:hlink><a:folHlink><a:srgbClr val="800080"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Cambria"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="1"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="100000"/><a:shade val="100000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="50000"/><a:shade val="100000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults><a:spDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style></a:spDef><a:lnDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style></a:lnDef></a:objectDefaults></a:theme>')
    zip.file(`xl/worksheets/sheet1.xml`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:etc="http://www.wps.cn/officeDocument/2017/etCustomData"><sheetPr/><dimension ref="A1:C4"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"><selection activeCell="C4" sqref="C4"/></sheetView></sheetViews><sheetFormatPr defaultColWidth="9" defaultRowHeight="14.25" outlineLevelRow="3" outlineLevelCol="2"/><sheetData>${
      
      sheetData}</sheetData><pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/><headerFooter/></worksheet>`)
    zip.file(`xl/_rels/workbook.xml.rels`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/></Relationships>')
    zip.file(`_rels/.rels`, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>')
    zip.generateAsync({
    
    type: "arraybuffer"})
        .then(function (content) {
    
    
        fs.writeFileSync(`${
      
      wx.env.USER_DATA_PATH}/result.xlsx`, content, 'utf-8');
        console.log(typeof (content));
        console.log(content);
        wx.hideLoading({
    
    
            success: (res) => {
    
    
                wx.openDocument({
    
    
                    filePath: `${
      
      wx.env.USER_DATA_PATH}/result.xlsx`,
                    showMenu: true,
                    fileType: 'xlsx',
                    success: function (res) {
    
    
                        console.log('打开文档成功', res)
                    }
                })
            },
        })
    })
}

For the specific structure of Excel, you can change the suffix to zip, and then unzip it to view. Most of the above files use the default content, only the two files xl/worksheets/sheet1.xml and xl/sharedStrings.xml have been modified. Among them, sheet1.xml is the specific data of the table, and sharedStrings.xml is similar to a dictionary. In order to save memory, the repeated content of cells will not be stored twice. But here I did not consider the problem of cell duplication.

Using the above method successfully runs through both Android and iOS, but the speed is not very fast.

4. Alternative methods

Also, here is an alternative. That is, instead of generating Excel, a csv file is generated instead. Although it cannot completely replace Excel, it can also have the effect of a table. code show as below:

const fs = wx.getFileSystemManager();
wx.showLoading({
    
    
    title: '正在生成',
})
let dataStr = ""
let keys = Object.keys(tableData[0])
//标题
for (let i = 0; i < keys.length; i++) {
    
    
    if (i != keys.length - 1) {
    
    
        dataStr += (keys[i] + ",")
    } else {
    
    
        dataStr += (keys[i] + "\n")
    }
}
//数据
for (let i = 0; i < tableData.length; i++) {
    
    
    for (let j = 0; j < keys.length; j++) {
    
    
        if (j != keys.length - 1) {
    
    
            dataStr += (tableData[i][keys[j]] + ",")
        } else {
    
    
            dataStr += (tableData[i][keys[j]] + "\n")
        }
    }
}
wx.showLoading({
    
    
    title: '正在写入',
})
fs.writeFileSync(`${
      
      wx.env.USER_DATA_PATH}/data.csv`, dataStr, "utf-8")
wx.hideLoading({
    
    
    success: (res) => {
    
    
        wx.showModal({
    
    
            title: '成功',
            content: '生成完成,是否分享',
            success(res) {
    
    
                if (res.confirm) {
    
    
                    wx.shareFileMessage({
    
    
                        filePath: `${
      
      wx.env.USER_DATA_PATH}/data.csv`,
                        success() {
    
    
                        },
                        fail: console.error,
                    })
                } else if (res.cancel) {
    
    
                }
            }
        })
    },
})

However, wx.openDocument does not support csv files, so I thought of opening it with other applications. However, Tencent Dog does not provide APIs that other programs can open, so the files are shared here after being generated. Tencent is a real dog!

Guess you like

Origin blog.csdn.net/ZackSock/article/details/125980913