【Node.js Express】EXCELファイルをバックアップし、DBに格納

エクセルファイルをアップロードしたら、バックアップを作成し、中身のデータをデータベースに登録するAPIを作りました。また似たような作業することになりそうなので、メモ。
Node.jsとExpress、データベースはMysqlを使用

#使うもの
１）multer
アップロードされたエクセルファイルを特定のファイルにコピーする。
※ただし、multipart/form-dataのみ
https://www.npmjs.com/package/multer

インストール：
```npm install --save multer```

２）sheetjs
エクセルファイルの書き換え等ができる。
今回はエクセルファイルをJSONに変換するのに使用した。
https://www.npmjs.com/package/xlsx

インストール：
```npm install --save xlsx```


#実装

``````javascript
const express = require('express')
const app = express()
const models = require('../model/models')
const xlsx = require('xlsx')
const multer = require('multer')
const storage = multer.diskStorage({
    //保存先を指定
  destination: function (req, file, cb) {
    cb(null, './uploads/excels')
  },
    //ファイル名の先端に日付をつけて保存
  filename:  function (req, file, cb) {
    cb(null, new Date().toISOString() + file.originalname)
  }
})

const fileFilter = (req, file, cb) => {
  //ファイルの拡張子を確認 とりあえず、excelとspredsheetを。
  if (file.mimetype === 'application/vnd.ms-excel' || file.minetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
    cb(null, true)
  } else {
    cb(null, false)
  }
}


const upload = multer({
  storage: storage,
  limits: {
    //アップロードできるファイル数
    files: 1,
    //ファイルサイズ（２MB@）
    fieldSize: 2 * 1024 * 1024
  },
  fileFilter: fileFilter
})

app.post('/upload' , upload.single('postしてくる時のキー'), async(req, res) => {
  try {
    const sheet = xlsx.readFile('./uploads/excels/' + req.file.filename, { cellDates: true })
    const workingSheet = sheet.Sheets['シート名']
    const data = xlsx.utils.sheet_to_json(workingSheet)
    //カラム名
    const fieldNames = ['date', 'name', 'tel']
    var dataArray = []
    for (var i in data) {
      //String型を明記しないとエラーになったので。　
      //エクセルのカラム名？（カラム最上セルのテキスト）日本語なのがアレなので良い方法あれば教えて欲しいです。
      //電話番号は -（ハイフン） を抜き取る。
      var insertData = `(${JSON.stringify(data[i].日付) || null}, ${JSON.stringify(data[i].名前) || null}, , ${data[i].電話番号.replace(/-/g, '') || null})`
      dataArray.push(insertData)
    }
    const tableName = 'テーブル名'
    //毎回データを総入れ替えする仕様のため、全データ消す
    const areDeleted = await models.deleteAll(tableName)
    if (!areDeleted) return res.status(500).json({ message: 'エラーが発生！' })
    //データを挿入
    const areInserted = await models.insertData(tableName, fieldNames, dataArray)
    if (!areInserted) return res.status(500).json({ message: 'エラー発生！' })
    return res.status(200).json({ message: '成功！' })
  } catch (err) {
    console.log(err)
    return res.status(500).json({ message: 'エラーが発生！' })
  }
})

```````

モデル抜粋

``````model.js
const mysql = require('mysql2')
const models = {}

// Setup database
const connection = mysql.createConnection({
  host: ホスト,
  user: ユーザー,
  password: パスワード,
  database: データベース名,
  port: ポート番号,
  multipleStatements: true //複数のコールを有効化
})

connection.connect((err) => {
  if (!err)
    console.log('接続成功')
  else
    console.log('接続失敗 : ' + JSON.stringify(err, undefined, 2))
})

models.deleteAll = (tableName) => {
  return new Promise((resolve, reject) => {
    connection.query('DELETE FROM ?', [tableName], (err, results) => {
      if (err) return reject(err)
      else return resolve(results)
    })
  })
}

models.insertData = (tableName, fieldName, insertData) => {
  return new Promise((resolve, reject) => {
    connection.query(`INSERT INTO ? (?) VALUES ?`, [tableName, fieldName, insertData],(err, results) => {
      if (err) return reject(err)
      else return resolve(results)
    })
  })
}

module.exports.models = models