エクセルファイルをアップロードしたら、バックアップを作成し、中身のデータをデータベースに登録するAPIを作りました。また似たような作業することになりそうなので、メモ。
Node.jsとExpress、データベースはMysqlを使用
#使うもの
1)multer
アップロードされたエクセルファイルを特定のファイルにコピーする。
※ただし、multipart/form-dataのみ
https://www.npmjs.com/package/multer
インストール:
npm install --save multer
2)sheetjs
エクセルファイルの書き換え等ができる。
今回はエクセルファイルをJSONに変換するのに使用した。
https://www.npmjs.com/package/xlsx
インストール:
npm install --save xlsx
#実装
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,
//ファイルサイズ(2MB@)
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