成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【實(shí)戰(zhàn)教程】使用云函數(shù)將數(shù)據(jù)表導(dǎo)出為 Excel 文件

iOS122 / 3548人閱讀

摘要:本文將介紹通過知曉云云函數(shù)來實(shí)現(xiàn)將數(shù)據(jù)表導(dǎo)出為文件的功能,并使用和將代碼打包上傳到知曉云。

在日常的工作中,常常需要根據(jù)運(yùn)營(yíng)需求對(duì)數(shù)據(jù)進(jìn)行各種格式的處理和導(dǎo)出。導(dǎo)出后,不少人偏愛將數(shù)據(jù)放入 excel 在進(jìn)行處理。

一般來說,處理數(shù)據(jù)導(dǎo)出時(shí)需要對(duì)數(shù)據(jù)進(jìn)行一些運(yùn)算整理。在以前,處理的方式是在一臺(tái)獨(dú)立的服務(wù)器上跑腳本。

而現(xiàn)在有了知曉云,不再需要維護(hù)服務(wù)器,直接寫代碼就能把相關(guān)事都都丟給云函數(shù)。 本文將介紹通過知曉云云函數(shù)來實(shí)現(xiàn)將數(shù)據(jù)表導(dǎo)出為 excel 文件的功能,并使用 webpackmincloud 將代碼打包上傳到知曉云。

技術(shù)棧:

打包工具:[email protected]

部署工具:[email protected]

Excel 處理:[email protected]

其他:知曉云 SDK

一、項(xiàng)目搭建

項(xiàng)目文件結(jié)構(gòu):

  export-excel-file
  ├── index.js
  ├── package.json
  ├── src
  │   └── index.js
  ├── webpack.config.js
  └── yarn.lock

項(xiàng)目搭建與云函數(shù)代碼打包示例文檔基本一致。項(xiàng)目搭建好后,還需要安裝以下依賴(兩種安裝方式選其一即可):

// 使用 yarn 安裝
yarn add node-xlsx mincloud
// 使用 npm 安裝
npm install --save node-xlsx minclou

修改 deploy 腳本,如下:

// package.json
...
"scripts": {
   "build": "webpack --mode production",
   "predeploy": "npm run build",
   "deploy": "mincloud deploy export-excel-file ../"
},
...

最終我們會(huì)使用以下兩個(gè)命令來部署和測(cè)試:

npm run deploy  // 部署到知曉云
mincloud invoke export-excel-file  // 測(cè)試已經(jīng)部署到知曉云上的云函數(shù)
二、將數(shù)據(jù)表導(dǎo)出為 excel 文件

我們需要準(zhǔn)備兩張表:
order: 訂單表 (新建字段:name, price)
export_task:導(dǎo)出任務(wù)記錄表 (新建字段:file_download_link)

知曉云的云函數(shù)調(diào)用有同步和異步兩種方式,同步調(diào)用的最大超時(shí)時(shí)間為 5 s,異步調(diào)用的則為 300 s。

假定 order 訂單表有十萬條數(shù)據(jù),由于知曉云單次拉取數(shù)據(jù)的最大限制為 1000 條,所以需要分批獲取數(shù)據(jù),加上后續(xù)可能需要對(duì)數(shù)據(jù)進(jìn)行處理,所花費(fèi)的時(shí)間將會(huì)超過 5 s,因此對(duì)該云函數(shù)的調(diào)用將采用異步的方式。這時(shí)候就需要 export_task 導(dǎo)出任務(wù)記錄表來對(duì)導(dǎo)出任務(wù)進(jìn)行管理了。

export_task 表對(duì)導(dǎo)出任務(wù)進(jìn)行管理的流程如下:

調(diào)用云函數(shù)時(shí)在 export_task 表中創(chuàng)建一條記錄 A,此時(shí)記錄 A 中的 file_download_link 字段值為空,同時(shí)拿到記錄 A 的 id,記這個(gè) id 為 jobId

進(jìn)行 order 表數(shù)據(jù)查詢,excel 文件生成,文件上傳等操作,拿到文件下載鏈接

之后根據(jù) jobId 來更新第一步創(chuàng)建的記錄,保存文件下載鏈接到 file_download_link 字段中

更新完后就能在 export_task 表中拿到文件下載鏈接

通過上面的準(zhǔn)備和分析,對(duì)導(dǎo)出 excel 文件操作分為以下 4 個(gè)步驟:

order 訂單表數(shù)據(jù)獲取

使用獲取的數(shù)據(jù)在云函數(shù)環(huán)境下創(chuàng)建 excel 文件

將創(chuàng)建出的 excel 文件上傳到知曉云

保存文件下載鏈接到 export_task 表中的 file_download_link 字段

完整代碼如下:

const fs = require("fs")
const xlsx = require("node-xlsx")


const EXPORT_DATA_CATEGORY_ID = "5c711e3119111409cdabe6f2"    // 文件上傳分類 id
const TABLE_ID = {
  order: 66666,         // 訂單表
  export_task: 66667,   // 導(dǎo)出任務(wù)記錄表
}


const TMP_FILE_NAME = "/tmp/result.xlsx"  // 本地臨時(shí)文件路徑,以 /tmp 開頭,具體請(qǐng)查看:https://doc.minapp.com/support/technical-notes.html (云函數(shù)的臨時(shí)文件存儲(chǔ))
const ROW_NAME = ["name", "price"]        // Excel 文件列名配置
const MAX_CONNECT_LIMIT = 5               // 最大同時(shí)請(qǐng)求數(shù)
const LIMIT = 1000                        // 單次最大拉取數(shù)據(jù)數(shù)
let result = []


/**
 * 更新導(dǎo)出記錄中的 file_download_link 字段
 * @param {*} tableID 
 * @param {*} recordId 
 * @param {*} fileLink 
 */
function updateExportJobIdRecord(tableID, recordId, fileLink) {
  let Schame = new BaaS.TableObject(tableID)
  let schame = Schame.getWithoutData(recordId)


  schame.set("file_download_link", fileLink)
  return schame.update()
}


/**
 * 創(chuàng)建數(shù)據(jù)導(dǎo)出任務(wù)
 * 設(shè)置初始 file_download_link 為空
 * 待導(dǎo)出任務(wù)執(zhí)行完畢后將文件下載地址存儲(chǔ)到 file_download_link 字段中
 * @param {*} tableID 
 */
function createExportJobIdRecord(tableID) {
  let Schame = new BaaS.TableObject(tableID)
  let schame = Schame.create()
  return schame.set({file_download_link: ""}).save().then(res => {
    return res.data.id
  })
}


/**
 * 獲取總數(shù)據(jù)條數(shù)
 * @tableId {*} tableId
 */
function getTotalCount(tableId) {
  const Order = new BaaS.TableObject(tableId)
  return Order.count()
    .then(num => {
      console.log("數(shù)據(jù)總條數(shù):", num)
      return num
    })
    .catch(err => {
      console.log("獲取數(shù)據(jù)總條數(shù)失敗:", err)
      throw new Error(err)
    })
}


/**
 * 分批拉取數(shù)據(jù)
 * @param {*} tableId 
 * @param {*} offset 
 * @param {*} limit 
 */
function getDataByGroup(tableId, offset = 0, limit = LIMIT) {
  let Order = new BaaS.TableObject(tableId)
  return Order.limit(limit).offset(offset).find()
    .then(res => {
      return res.data.objects
    })
    .catch(err => {
      console.log("獲取分組數(shù)據(jù)失敗:", err)
      throw new Error(err)
    })
}


/**
 * 創(chuàng)建 Excel 導(dǎo)出文件
 * @param {*} sourceData 源數(shù)據(jù)
 */
function genExportFile(sourceData = []) {
  const resultArr = []
  const rowArr = []


  // 配置列名
  rowArr.push(ROW_NAME)


  sourceData.forEach(v => {
    rowArr.push(
      ROW_NAME.map(k => v[k])
    )
  })


  resultArr[0] = {
    data: rowArr,
    name: "sheet1",    // Excel 工作表名
  }


  const option = {"!cols": [{wch: 10}, {wch: 20}]}    // 自定義列寬度
  const buffer = xlsx.build(resultArr, option)
  return fs.writeFile(TMP_FILE_NAME, buffer, err => {
    if (err) {
      console.log("創(chuàng)建 Excel 導(dǎo)出文件失敗")
      throw new Error(err)
    }
  })
}


/**
 * 上傳文件
 */
function uploadFile() {
  let MyFile = new BaaS.File()
  return MyFile.upload(TMP_FILE_NAME, {category_id: EXPORT_DATA_CATEGORY_ID})
    .catch(err => {
      console.log("上傳文件失敗")
      throw new Error(err)
    })
}


module.exports = async function(event, callback) {
  try {
    const date = new Date().getTime()
    const groupInfoArr = []
    const groupInfoSplitArr = []
    const [jobId, totalCount] = await Promise.all([createExportJobIdRecord(TABLE_ID.export_task), getTotalCount(TABLE_ID.order)])
    const groupSize = Math.ceil(totalCount / LIMIT) || 1


    for (let i = 0; i < groupSize; i++) {
      groupInfoArr.push({
        offset: i * LIMIT,
        limit: LIMIT,
      })
    }


    console.log("groupInfoArr:", groupInfoArr)


    const length = Math.ceil(groupInfoArr.length / MAX_CONNECT_LIMIT)


    for (let i = 0; i < length; i++) {
      groupInfoSplitArr.push(groupInfoArr.splice(0, MAX_CONNECT_LIMIT))
    }


    console.log("groupInfoSplitArr:", groupInfoSplitArr)


    const date0 = new Date().getTime()
    console.log("處理分組情況耗時(shí):", date0 - date, "ms")


    let num = 0


    // 分批獲取數(shù)據(jù)
    const getSplitDataList = index => {
      return Promise.all(
        groupInfoSplitArr[index].map(v => {
          return getDataByGroup(TABLE_ID.order, v.offset, v.limit)
        })
      ).then(res => {
        ++num
        result.push(...Array.prototype.concat(...res))
        if (num < groupInfoSplitArr.length) {
          return getSplitDataList(num)
        } else {
          return result
        }
      })
    }


    Promise.all([getSplitDataList(num)]).then(res => {
      const date1 = new Date().getTime()
      console.log("結(jié)果條數(shù):", result.length)
      console.log("分組拉取數(shù)據(jù)次數(shù):", num)
      console.log("拉取數(shù)據(jù)耗時(shí):", date1 - date0, "ms")


      genExportFile(result)


      const date2 = new Date().getTime()
      console.log("處理數(shù)據(jù)耗時(shí):", date2 - date1, "ms")


      uploadFile().then(res => {
        const fileLink = res.data.file_link
        const date3 = new Date().getTime()
        console.log("上傳文件耗時(shí):", date3 - date2, "ms")
        console.log("總耗時(shí):", date3 - date, "ms")


        updateExportJobIdRecord(TABLE_ID.export_task, jobId, fileLink)
          .then(() => {
            const date4 = new Date().getTime()
            console.log("保存文件下載地址耗時(shí):", date4 - date3, "ms")
            console.log("總耗時(shí):", date4 - date, "ms")


            callback(null, {
              message: "保存文件下載地址成功",
              fileLink,
            })
          })
          .catch(err => {
            callback(err)
          })
      }).catch(err => {
        console.log("上傳文件失?。?, err)
        throw new Error(err)
      })
    })
  } catch (err)
三、部署并測(cè)試

npm 一樣,部署前需要先登錄,請(qǐng)參照文檔配置。

使用以下命令即可將云函數(shù)部署到知曉云:

npm run deploy

執(zhí)行結(jié)果如下:

使用以下的命令來測(cè)試:

mincloud invoke export-excel-file

執(zhí)行結(jié)果如下:

export_task 表記錄:

上傳到知曉云的 excel 文件如下:

文件內(nèi)容:

四、參考文檔

知曉云開發(fā)文檔:https://doc.minapp.com/
node-xlsx 文檔:https://www.npmjs.com/package...

五、源碼

倉庫地址:https://github.com/ifanrx/exp...

六、福利

即日( 3 月 8 日)起,前 50 名報(bào)名并通過審核的 Web 端公測(cè)的用戶,在正式接入后即獲賬戶禮金 100 元。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109043.html

相關(guān)文章

  • 使用 SpreadJS 實(shí)現(xiàn) JavaScript 中導(dǎo)入和導(dǎo)出Excel文件

    摘要:而作為一款深受用戶喜愛的電子表格工具,借助其直觀的界面出色的計(jì)算性能和圖表工具,已經(jīng)成為數(shù)據(jù)統(tǒng)計(jì)領(lǐng)域不可或缺的軟件之一。使用實(shí)現(xiàn)的導(dǎo)入和導(dǎo)出通過純,您完全可以實(shí)現(xiàn)導(dǎo)入和導(dǎo)出文件功能,并為最終用戶提供與這些文件進(jìn)行交互的界面。 JavaScript是一個(gè)涵蓋多種框架、直譯式、可以輕松自定義客戶端的腳本語言,在 Web 應(yīng)用程序中,更加易于編碼和維護(hù)。而Excel 作為一款深受用戶喜愛的電...

    Jioby 評(píng)論0 收藏0
  • 實(shí)戰(zhàn)PHP導(dǎo)出Excel-CSV文件

    摘要:中國(guó)大陸幾乎所有的中文系統(tǒng)和國(guó)際化的軟件都支持。與相應(yīng)的國(guó)家標(biāo)準(zhǔn)中的其它漢字,以上合計(jì)個(gè)漢字。,全稱國(guó)家標(biāo)準(zhǔn)信息技術(shù)中文編碼字符集,是中華人民共和國(guó)現(xiàn)時(shí)最新的內(nèi)碼字集,是信息技術(shù)信息交換用漢字編碼字符集基本集的擴(kuò)充的修訂版。 實(shí)戰(zhàn)PHP導(dǎo)出Excel-CSV文件 導(dǎo)出后的效果 先給各位看一下導(dǎo)出的效果,而后再進(jìn)行代碼分析 showImg(https://segmentfault.co...

    Kyxy 評(píng)論0 收藏0
  • 實(shí)戰(zhàn)PHP導(dǎo)出Excel-CSV文件

    摘要:中國(guó)大陸幾乎所有的中文系統(tǒng)和國(guó)際化的軟件都支持。與相應(yīng)的國(guó)家標(biāo)準(zhǔn)中的其它漢字,以上合計(jì)個(gè)漢字。,全稱國(guó)家標(biāo)準(zhǔn)信息技術(shù)中文編碼字符集,是中華人民共和國(guó)現(xiàn)時(shí)最新的內(nèi)碼字集,是信息技術(shù)信息交換用漢字編碼字符集基本集的擴(kuò)充的修訂版。 實(shí)戰(zhàn)PHP導(dǎo)出Excel-CSV文件 導(dǎo)出后的效果 先給各位看一下導(dǎo)出的效果,而后再進(jìn)行代碼分析 showImg(https://segmentfault.co...

    molyzzx 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<