浏览器、H5移动端页面预览excel xlsx文件(sheetjs)

浏览器H5中渲染excel/xlsx文件

本文主要使用 [SheetJS](Overview | SheetJS Community Edition)来实现在web浏览器公众号H5等页面中实现预览excel的功能。

1. 安装使用SheetJS

  • 通过cdn网络引入sheetjs

    <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
    
  • 把js文件下载到项目本地调用

    把cdn或者npm中对应js代码保存的项目本地然后调用。

  • npm/yarn安装。[npm地址](xlsx - npm (npmjs.com))

    yarn add https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz
    npm install xlsx
    

2. 页面展示

  • 把oss或者服务器上获取的表格文件转换成json格式,然后用json数据在页面渲染出来效果,可以自定义表格样式。推荐使用该方式

    1. web浏览器原生html实现

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Excel xlsx</title>
        <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
        <style> #app { width: 100%; height: 100%; border: 1px solid red; } </style>
      </head>
      <body>
        <table id="table-container" border="1"></table>
        <script>
          window.onload = async () => {
            const filePath = 'https://oss.xxxxx/demo-slxs.xlsx' // xlsx链接地址
            const wb = XLSX.read(await (await fetch(filePath)).arrayBuffer())
            const ws = wb.Sheets[wb.SheetNames[0]]
            const data = XLSX.utils.sheet_to_json(ws, {header: 1})
            /**
             * 解析出的data中第一行[index === 0]是table header 下的是对应每一行的数据。
             * 得到json格式的数据后,可以根据自己工程使用的技术框架选择如何渲染表格
             * 这里使用原生html拼接生成table
             */
            const tableEl = document.getElementById('table-container')
            let theaderContent = ''
            data[0].forEach(headItem => { // index = 0 是表头信息
              theaderContent += `<th>${headItem}</th>`
            })
            let tableRowContent = ''
            data.forEach((row,index) => {
              if (index !== 0) {
                let currRow = `<tr>`
                row.forEach(rowItem => { currRow += `<td>${rowItem}</td>` })
                currRow += `</tr>`
                tableRowContent += currRow
              }
            })
            tableEl.innerHTML = `<table> <thead><tr>${theaderContent}</tr></thead> <tbody>${tableRowContent}</tbody> </table>`
          }
        </script>
      </body>
      </html>
      
  1. VUE项目中实现。需要npm安装sheetjs。

    <script setup lang="ts">
    import { read, utils } from 'xlsx'
    import { ref, onMounted } from 'vue'
    const tableData = ref([])
    const tableHead = ref([])
    onMounted(() => { InitTableData() })
    const InitTableData = async () => {
      const filePath = 'https://oss.xxxx/demo-slxs.xlsx' // 表格链接地址
      const wb:any = read(await (await fetch(filePath)).arrayBuffer())
      const ws = wb.Sheets[wb.SheetNames[0]]
      const data:any = utils.sheet_to_json(ws, {header: 1})
      /**
       * 解析出的data中第一行[index === 0]是table header 下的是对应每一行的数据。
        * 得到json格式的数据后,可以根据自己工程使用的技术框架选择如何渲染表格
        * 这里使用原生vue3+elementPlus-table生成table
       */
      tableHead.value = data[0]
      data.forEach((row:any, index:number) => {
        if (index !== 0) { // 第一行是表头信息
          const tmp:any = {}
          row.forEach((item:any, i:number) => {
            tmp[data[0][i]] = item || '-'
          })
          tableData.value.push(tmp)
        }
      })
    }
    </script>
    <template>
      <el-table :data="tableData" style="width: 100%; height: 600px;">
        <el-table-column v-for="item in tableHead" :prop="item" :label="item" :key="item" />
      </el-table>
    </template>
    
  2. uniapp H5中实现(如果是小程序或者app等可以使用 uniapp原生uni.openDocument(object)方法实现)

    <template>
      <view class="xlsx-container">
        <zb-table
          border
          :show-header="true"
          :columns="tableColumns"
          :stripe="true"
          :fit="true"
          :data="tableData"></zb-table>
      </view>
    </template>
    <script>
    /**
     * 在页面渲染xlsx文件,使用sheetjs来做。 还可以调用微软的链接地址进行渲染xlsx。
     * 本组件有两种渲染方式heetjs。 开源可以npm下载源码方式。
     * npm i --save https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz
     *  1. 把拿到的xlsx文件直接使用 sheet_to_html 来渲染,样式默认,不好看。
     *  2. 先把拿到xlsx文件解析成js识别的 json 格式的数据,然后使用 ui 的table相关组件进行渲染。
     * 推荐使用第2种方式。调用了uniapp 插件市场的 zb-table。
     * 需要接收的参数是 xlsx 文件的oss的链接地址。
     */
    import { read, utils } from 'xlsx'
    
    import zbTable from 'uni_modules/components/zb-table/components/zb-table/zb-table.vue'
    
    export default {
      name: 'scanXlsx',
      props: {
        filePath: {
          type: String,
          default: '',
          required: true
        }
      },
      data () {
        return {
          tableColumns: [],
          tableData: []
        }
      },
      components: { zbTable },
      mounted () {
        this.initViewer()
      },
      methods: {
        async initViewer () {
          const filePath ='https://oss.xxxxx/demo-slxs.xlsx'
          let wb = null
          try {
            read(await (await fetch(filePath)).arrayBuffer())
          } catch (error) {
            uni.showToast({
              title: '预览失败!',
              icon: 'none',
              mask: true
            })
          }
          if (wb) {
            const ws = wb.Sheets[wb.SheetNames[0]]
            // 把数据解析成json然后再渲染
            const data = utils.sheet_to_json(ws, {header: 1})
            // data数据是json数据,第一行是表头数据
            if (data && data.length > 1) {
              data.forEach((row, index) => {
                if (index === 0) {
                  this.tableColumns = row.map((th, index) => ({label: th, name: `prop${index}`}))
                } else {
                  const tmp = {}
                  row.forEach((td, index) => {
                    tmp[`prop${index}`] = td || '-'
                  })
                  this.tableData.push(tmp)
                }
              })
            } 
          }
    
          // 使用sheet_to_html直接渲染table,样式不好看
          /* const viewer = document.getElementById('xlsx-container')
          viewer.innerHTML = utils.sheet_to_html(ws) */
        }
      }
    }
    </script>
    
    <style scoped>
    .xlsx-container {
      width: 100%;
      height: 100%;
      overflow: scroll;
    }
    </style>
    
    
  1. 其他平台遇见再更新
  • 把oss或者服务器返回的数据转成 arrayBuffer 文件格式,然后使用sheetjs的sheet_to_html方法渲染在web浏览器页面上。

    1. web浏览器原生html实现

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Excel xlsx</title>
        <script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
        <style> #app { width: 100%; height: 100%; border: 1px solid red; } </style>
      </head>
      <body>
        <table id="table-container" border="1"></table>
        <script>
          window.onload = async () => {
            const filePath = 'https://prod-any-image.oss-cn-shenzhen.aliyuncs.com/bigscreen/project/bjl4/lines-json/demo-slxs.xlsx'
            const wb = XLSX.read(await (await fetch(filePath)).arrayBuffer())
            const ws = wb.Sheets[wb.SheetNames[0]]
            const output = document.getElementById('table-container')
            output.innerHTML = XLSX.utils.sheet_to_html(ws)
          }
        </script>
      </body>
      </html>
      
    2. VUE项目中实现。需要npm安装sheetjs。

      <script setup lang="ts">
      import { read, utils } from 'xlsx'
      import { ref, onMounted } from 'vue'
      onMounted(() => {InitTableData()})
      const InitTableData = async () => {
        const filePath = 'https://osss.xxxxxxxxx/demo-slxs.xlsx' // 表格链接地址
        const wb:any = read(await (await fetch(filePath)).arrayBuffer())
        const ws = wb.Sheets[wb.SheetNames[0]]
        /**
         * 使用 sheet_to_html 渲染原生table的样式
         */
        const output:any = document.getElementById('table-container')
        output.innerHTML = utils.sheet_to_html(ws)
      }
      </script>
      <template>
        <table id="table-container" border="1"></table>
      </template>
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容