Как правильно экспортировать файл, созданный в временной папке узла, через http res.sendFile (...) или res.download (...) - PullRequest
0 голосов
/ 28 января 2019

Проблема в том, что файл Excel, который я создаю в приложении node / express, загружает файл с нулевыми байтами через http.Что я должен делать, чтобы загрузить файл с данными?

У меня есть код узла / экспресса, который генерирует файл Excel и сохраняет его во временную папку.В конечном итоге я собираюсь перенести этот код в облачные функции Google, как только он заработает.Проблема в том, что, хотя файл excel создается с данными (как я вижу это в папке temp), res.download (имя файла) через http загружает файл с нулевыми байтами.Что я должен делать, чтобы загрузить файл с данными?

Пример кода приведен ниже.Пожалуйста, игнорируйте значение данных примера, закомментированного кода и console.logs

// import * as functions from 'firebase-functions';
import * as Excel from 'exceljs';
import * as express from 'express';
import * as os from 'os';
import * as path from 'path';


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


interface Country { 
    id: number; 
    country: string; 
    capital: string; 
    population: number; 
}

interface Heading { 
    header: string; 
    key: string; 
    width: number; 
}

interface Align { col: string; align: string; }

function addBottomBorder(worksheet: any, cols: number, rowNo: number) {
    for (let i = 0; i < cols; i++) {
        const col = String.fromCharCode(65 + i) + rowNo;

        worksheet.getCell(col).border = {
            bottom: {style:'thin'},
        };
    }
}

function hiliteRow(worksheet: any, row: number, color: string, cols: number) {
    for (let i = 0; i < cols; i++) {
        const col = String.fromCharCode(65 + i) + row;

        worksheet.getCell(col).fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: { argb: color }
        };
    }
}

function createHeadings(worksheet: any, headings: Heading[]) {
    worksheet.columns = headings;

    hiliteRow(worksheet, 1, '808B96', headings.length);
    addBottomBorder(worksheet, headings.length, 1);

    // add filters
    const lastColumn = String.fromCharCode(64 + headings.length);
    worksheet.autoFilter = { from: 'A1', to: `${lastColumn}1`, };
}

async function generate(data: Country[], headings: Heading[], sheetname: string, alignments: Align[]) {

    const workbook = new Excel.Workbook();
    const worksheet: any = workbook.addWorksheet(sheetname);

    createHeadings(worksheet, headings);

    for (const alignObj of alignments) {
        worksheet.getColumn(alignObj.col).alignment = { vertical: 'middle', horizontal: alignObj.align };
    }

    data.forEach((r: any , i: number) => {
        worksheet.addRow(r);

        if (i % 2 !== 0) {
            hiliteRow(worksheet, i + 2, 'D6DBDF', headings.length)
        }
    });

    addBottomBorder(worksheet, headings.length, data.length + 1);

    console.log(tempFilePath);
    workbook.xlsx.writeFile(tempFilePath).then( result => {
        console.log('...ready', result)
        return tempFilePath;
    })
    .catch( err => {
        return err;
    })

}


app.get('/', async (req, res) => {

    const alignments = [
        { col: 'A', align: 'left'},
        { col: 'D', align: 'right'},
    ];

    const columns = [
        { header: 'ID', key: 'id', width: 4 },
        { header: 'Country', key: 'country', width: 10 },
        { header: 'Capital', key: 'capital', width: 22 },
        { header: 'Population', key: 'population', width: 9 }
    ];

    const data = [{
            id: 1,
            country: 'USA',
            capital: 'Washington DC',
            population: 325
        }, {
            id: 2,
            country: 'UK',
            capital: 'London',
            population: 66
        }, {  
            id: 3,
            country: 'Italy',
            capital: 'Rome',
            population: 60.59
        }, {
            id: 4,
            country: 'China',
            capital: 'Beijing',
            population: 1386
        }, {
            id: 5,
            country: 'Canada',
            capital: 'Ottawa',
            population: 36.7
        }, {
            id: 6,
            country: 'UK',
            capital: 'London',
            population: 66
        }, {
            id: 7,
            country: 'Italy',
            capital: 'Rome',
            population: 60.59
        }, {
            id: 8,
            country: 'China',
            capital: 'Beijing',
            population: 1386
        }, {
            id: 9,
            country: 'Canada',
            capital: 'Ottawa',
            population: 36.7
        }
    ];

    const sheetname = 'countries';
    try {
        generate(data, columns, sheetname, alignments).then( notImportant => {
            console.log(notImportant);



            // !!!!!!!!! - a file with zero bytes is downloaded
            // !!!!!!!!! - same result with res.sendFile(...)

            res.status(200).download(tempFilePath);
        })

    } catch (error) {
        res.status(500).send(error);
    }
})

app.listen(3001, () => {
    console.log('...listening')
})

// exports.getExcel = functions.https.onRequest(app);

1 Ответ

0 голосов
/ 28 января 2019

Решением для меня этой проблемы было создание 2 конечных точек - 1 для генерации файла и второй для загрузки файла

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...