LoginSignup
6
6

More than 5 years have passed since last update.

Firebase Cloud functionsでEXCELを読み込んで書き込む

Last updated at Posted at 2018-07-04

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();
                        };
                    })
            })

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6