Firebase Cloud functionsでEXCELを作って画面側でダウンロードさせたい!
探してもあまり出てこないので初めて書いてみました
実現すること
Firebase functionsで、Firebase storageに置いたEXCELひな形ファイルを読み込み、書き込んでからstorageに新ファイルとして書き込む。
functionは画面上のボタンクリックからHTTP リクエストで呼び出し、そのファイルをダウンロードさせる。
functions側
index.js
const cors = require('cors')({ origin: true });
const functions = require('firebase-functions');
const keyFilename = "./credential/XXXXXXXX.json";
const projectId = "project-id";
const gcs = require('@google-cloud/storage')({
projectId,
keyFilename
});
const bucket = gcs.bucket("ikeiketest");
const path = require('path');
const os = require('os');
exports.createExcel = functions.https.onRequest((req, res) => {
const moment = require('moment');
cors(req, res, () => {
// storage上のファイル名
var fileName = 'template.xlsx';
// テンプレートファイルを一時的に置く場所のパス
const tempFilePath = path.join(os.tmpdir(), fileName);
bucket
.file(fileName)
.download({
destination: tempFilePath
})
.catch(err => {
console.error('テンプレファイルダウンロードエラー:', err);
})
.then(() => {
const newFileName = 'sample.xlsx';
const newFilePath = path.join(os.tmpdir(), newFileName);
const metadata = { "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" };
var Excel = require('exceljs');
var workbook = new Excel.Workbook();
// テンプレートのEXCELを読み込む
workbook.xlsx.readFile(tempFilePath).then(function () {
// なにか書き込む
var sheet1 = workbook.getWorksheet(1)
sheet1.getCell(rownum, 3).value = '書き込んだよ';
// 書き込んだファイルを保存
workbook.xlsx.writeFile(newFilePath).then(function () {
// storage上のパス
var destPath = '/tmp/' + newFileName;
bucket.upload(newFilePath
, {
destination: destPath, metadata: metadata
}).then(function () {
res.status(200).send(destPath);
})
})
})
})
});
});
画面側
main.js
axios.post('createExcel'
, {
// 本当はfirebase authenticationのtokenを送って認証する
token: token,
})
.then(function (response) {
var storage = firebase.storage();
var pathReference = storage.ref(response.data);
pathReference.getDownloadURL()
.then(function (url) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
var blob;
xhr.open('GET', url);
xhr.send();
return xhr;
})
.catch(function (error) {
console.log(error.message);
})
.then(function (xhr) {
xhr.onload = function (event) {
blob = xhr.response;
saveAs(blob, fileName);
resolve();
};
})
})