TransWikia.com

How to read file from createReadStream in Node.js?

Stack Overflow Asked by ton1 on December 22, 2021

I have web appication that can upload excel file. If user upload, the app should parse it and will return some rows that file have. So, The application don’t need to save file to its filesystem. Parsing file and return rows is a job. But below code, I wrote this morning, it save file to its server and then parse it.. I think it’s waste server resource.

I don’t know how to read excel file with createReadStream. Without saving file, how can I parse excel directly? I am not familiar with fs, of course, I can delete file after the job finished, but is there any elegant way?

import { createWriteStream } from 'fs'
import path from 'path'
import xlsx from 'node-xlsx'

// some graphql code here... 


async singleUpload(_, { file }, context) {
    try {
    console.log(file)
    const { createReadStream, filename, mimetype, encoding } = await file

    await new Promise((res) =>
        createReadStream()
        .pipe(createWriteStream(path.join(__dirname, '../uploads', filename)))
        .on('close', res)
    )

    const workSheetsFromFile = xlsx.parse(path.join(__dirname, '../uploads', filename))
    for (const row of workSheetsFromFile[0].data) {
        console.log(row)
    }

    return { filename }
    } catch (e) {
    throw new Error(e)
    }
},

3 Answers

you can add an event listener before you pipe the data, so you can do something with your file before it uploaded, it look like this


async singleUpload(_, { file }, context) {
    try {
    console.log(file)
    const { createReadStream, filename, mimetype, encoding } = await file

    await new Promise((res) =>
        createReadStream()
        .on('data', (data)=>{
         //do something with your data/file
        console.log({data})
        //your code here
        })
        .pipe(createWriteStream(path.join(__dirname, '../uploads', filename)))
        .on('close', res)
    )
 
},

you can see the documentation stream node js

Answered by CheapImpact on December 22, 2021

var xlsx = require('xlsx')

//var workbook = xlsx.readFile('testSingle.xlsx')
var workbook = xlsx.read(fileObj);

You just need to use xlsx.read method to read a stream of data.

Answered by Sachin Sharma on December 22, 2021

Using express-fileupload library which provides a buffer representation for uploaded files (through data property), combined with excel.js which accepts a buffers will get you there.

see Express-fileupload and Excel.js

// read from a file
const workbook = new Excel.Workbook();
await workbook.xlsx.readFile(filename);
// ... use workbook


// read from a stream
const workbook = new Excel.Workbook();
await workbook.xlsx.read(stream);
// ... use workbook


// load from buffer  // this is what you're looking for
const workbook = new Excel.Workbook();
await workbook.xlsx.load(data);
// ... use workbook

Here's a simplified example:

const app = require('express')();
const fileUpload = require('express-fileupload');
const { Workbook } = require('exceljs');

app.use(fileUpload());

app.post('/', async (req, res) => {
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }
     // The name of the input field (i.e. "myFile") is used to retrieve the uploaded file
    await new Workbook().xlsx.load(req.files.myFile.data)
});

app.listen(3000)

Answered by Rafi Henig on December 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP