フロントから渡ってきたexcelファイルをAPI側でゴニョゴニョするようなものを作る必要があったのですが、妙に詰まったので備忘録として残します。
追記
そもそもexcelのバイナリをAPIに投げる必要はなく、フロント側でxlsxを使ってexcelデータをゴニョゴニョした方がシンプルでした。
環境
front側 react/redux
server側 koa
コード
excelを選択するとhandleExcelFileが発火
<input
name="file"
type="file"
placeholder="excel選択"
onChange={this.handleExcelFile}
/>
handleExcelFileではexcelファイルをバイナリにしてAPIに投げる
handleExcelFile = e => {
const htmlInputElement = e.target;
const excelFile = htmlInputElement.files[0];
const reader = new FileReader();
reader.readAsBinaryString(excelFile);
reader.onload = e => {
binaryExcelFile = e.target.result;
axios({
method: 'post',
url: 'apiのパス',
data: {
binaryExcelFile
}
});
};
xlsxを使ってexcelのデータを取得
const xlsx = require('xlsx');
module.exports = async (ctx, next) => {
const { binaryExcelFile } = ctx.request.body;
const excelData = xlsx.read(binaryExcelFile, { type: 'binary' });
// あとはexcelのデータを好きにいじる
};
詰まったところ
ネットでexcelファイルをapiに投げる例を検索すると、フロント側ではexcelをフォームのデータとして送信して
let formData = new FormData();
formData.append('file', excelFile, excelFile.name);
// このformDataをbodyで渡す
サーバー側ではkoa-multerを使って、送られてきたexcelを一時保存してから、その保存パスを指定する形でxlsxで読み込む、みたいなものばかりが引っかかってきました。が、なかなかうまく行きませんでした。
また、API側でctx.request.bodyの中身が空っぽというのにもぶち当たりました。原因としてはサーバー側でのbodyのパースにkoa-better-bodyというものを使っていたせいでした。素直にkoa-bodyparserを使っていればよかった、、
excelファイルをサーバー側にアップロードするような要件の場合にkoa-multerを使うのはいいと思いますが、今回のようなexcelの値だけに用がある場合はこれで十分な気がします。