创建 xlsx 文件,保存在 tmp 中并将其附加到 firebase 邮件中

问题描述

我创建了一个谷歌云函数,当它被触发时,它会创建一个带有 exceljs 的 xlsx 文件,并将其附加到使用 firebase-send-mail 发送的电子邮件中。 这是我的代码

(数据为虚拟测试)

exports.onEventReservCreate = functions
    .region("europe-west2")
    .firestore.document(
        "foodCourts/{foodCourtId}/events/{eventId}/eventReservations/{evtResId}"
    )
    .onCreate(async (snap,context) => {

        try {
            const excel = require("exceljs")

            //Creating New Workbook
            var workbook = new excel.Workbook()

            //Creating Sheet for that particular WorkBook
            var sheet = workbook.addWorksheet("Sheet1")

            // set path for file
            const tempFilePath = path.join(os.tmpdir(),"excel.xlsx")


            sheet.columns = [
                { key: "name",header: "name" },{ key: "age",header: "age" },]


            var data = [
                { name: "Eddy",age: 24 },{ name: "Paul",]

            //adding each in sheet
            data.forEach(el => sheet.addRow(el))

            // get the user email from firestore db
            const userRef = db.collection(`users`).doc(uid)
            const user = (await userRef.get()).data()

            workbook.xlsx
                .writeFile(tempFilePath)
                .then(res => {

                    // sending email to user
                    const emailData = {
                        to: [user.email],template: {
                            name: "reportEvents",data: {
                                attachmentPath: tempFilePath,attachmentName: "nome allegato",date: dateFnsTz.format(
                                    new Date(),"dd/MM/yyyy - HH:mm"
                                ),},}

                    return db.collection("email").doc().set(emailData)
                })
                .catch(err => console.log("ERROR --> ",err))
        } catch (err) {
            console.log(
                `Error while sending - Error: ${err}`
            )
        }
    })

函数日志中我有这个错误

发送消息时出错=email/[id]:错误:ENOENT:没有那个文件或目录,打开'/tmp/excel.xlsx'

为什么 /tmp 文件夹不存在?

谢谢

解决方法

临时文件夹的访问权限有限,我不确定您的电子邮件脚本实际上是如何读取文件的,因为它可能只是根文件夹问题或实例问题。相反,我会使用唯一的下载链接将文件上传到存储,并通过您的电子邮件发送。

,

解决了!

这是我的代码

它需要一些包,比如 node-fs、os、path。

此代码将创建 xslx 文件,将其存储在您的存储桶中,检索其 url 并在“电子邮件”集合中添加一个具有“url”属性的新文档,即存储桶中 xslx 文件的 url,因此用户将收到邮件可以下载。

const admin = require("firebase-admin")
const fs = require("fs")
const path = require("path")
const os = require("os")
const excel = require("exceljs")

const batch = db.batch()

const bucket = admin.storage().bucket("your_bucket's_name")

//Creating New Workbook
var workbook = new excel.Workbook()

//Creating Sheet for that particular WorkBook
var sheet = workbook.addWorksheet("Sheet1")

//Header must be in below format
sheet.columns = [
   { key: "name",header: "name",width: 30 },...other columns
]


//Data must be look like below,key of data must be match to header.
sheet.addRow({name: "John"}))

const tempFilePath = path.join(os.tmpdir(),"excel.xlsx")

await workbook.xlsx.writeFile(tempFilePath)

const destinationName = `[your_filename].xlsx`

const result = await bucket.upload(tempFilePath,{
    destination: destinationName,})

result[0].getSignedUrl({
    action: "read",expires: "03-17-2025",// choose a date
}).then((url,err) => {
    if (err) {
       console.log(err)
    }
    const emailData = {
       to: ["user_email"],template: {
          name: "your_template's_name",data: {
             url,},}

    const emailRef = db.collection("email").doc()

    batch.set(emailRef,emailData)

    return batch.commit()
}).catch(err => console.log(err))