微信小程序生成Excel

微信小程序生成Excel

一、问题描述

最近一直在查找在微信小程序中生成Excel的办法。需求就是根据一个json数据或者对象数组,生成一个Excel文件,或者打开Excel文件。网上找了很久,没找到很有效的解决办法。最后自己动手做了一个,不过生成效率还比较低。

二、实现思路

我比较赞同的方法有两种,第一种是使用api来实现。如果你有个服务器,那么一切就好办了。只需要把数据传给服务器,然后服务器生成Excel文件,并返回文件的url。之后通过wx.downloadFile下载文件,配合wx.openDocument打开文件即可。至于如何编写一个返回Excel文件url的api,方法就太多了。

但是不是所有人都有服务器,所以还得相关离线的办法生成Excel文件。我的思路是,Excel文件本身是一个压缩文件,我们只需要安装Excel的目录结构,逐个文件和文件夹创建,如何将文件压缩为xx.xlsx文件即可。

结果查找,腾讯狗没有提供压缩相关的api。不过js倒是有现成jszip库可以使用,有了jszip,我们就可以开始实现了。

三、具体实现

先下载jszip库,然后将dist中的js文件放到小程序下的utils目录下。

在pages/index/index.wxml中写个按钮:

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

然后在pages/index/index.js中最上面导入JSZip:

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

并编写响应函数:

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)
                    }
                })
            },
        })
    })
}

Excel的具体结构可以把后缀改成zip,然后解压查看。上面大多数文件都使用了默认的内容,只有xl/worksheets/sheet1.xml和xl/sharedStrings.xml两个文件进行了修改。其中sheet1.xml是表的具体数据,而sharedStrings.xml类似于一个词典,为了节约内存,单元格重复内容不会存储两次。不过这里我没有去考虑单元格重复的问题。

使用上面的方法在Android和iOS都成功跑通了,不过速度不是很快。

四、替代方法

另外,这里提供一个替代方案。就是不生成Excel,转而生成csv文件。虽然不能完全替代Excel,但是也能有表格的效果。代码如下:

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) {
    
    
                }
            }
        })
    },
})

不过wx.openDocument不支持csv文件,所以想到用其它应用打开。但是腾讯狗也没有提供其它程序打开的api,所以这里生成后分享文件。腾讯真狗!

猜你喜欢

转载自blog.csdn.net/ZackSock/article/details/125980913