Click Below to subscribe

How to Import Export Excel & CSV In Node.js 2022

In this article, we gonna learn how to import and export excel and csv in node.js. 

1. Let's create a new express project using express generator.

npm i -g express-generator
express node-excel-csv --view=hbs

2. Create a folder config and inside this create a file database.js.

config/database.js

module.exports = { 
    host: process.env.DB_HOST,
    database: process.env.DB_DATABASE,
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD
}

3. Install dotenv npm package.

npm i dotenv

After Installation import dotenv in app.js

require('dotenv').config();

4. Create a .env file in the root and add these environment variables.

DB_HOST=localhost            // your database host
DB_DATABASE=node-excel-csv  // your database name
DB_USERNAME=root           // your database username 
DB_PASSWORD=              // your database password

5. Install sequelize and mysql2 npm packages.

npm i sequelize mysql2

6. Create a models folder and inside this create a connection.js and movie.model.js

models/connection.js

const { Sequelize } = require('sequelize');
const config = require('../config/database'); 

const sequelize = new Sequelize(config.database, config.username, config.password, {
    host: config.host,
    dialect: 'mysql',
    operatorsAliases: 'false',
    logging: false
});  

module.exports = sequelize

models/movie.model.js

const { DataTypes } = require('sequelize');
const sequelize = require('./connection');

const Movie = sequelize.define('Movie', {
    movie: {
        type: DataTypes.STRING 
    },
    category: {
        type: DataTypes.STRING 
    },
    director: {
        type: DataTypes.STRING 
    },
    rating: {
        type: DataTypes.FLOAT(8, 1) 
    }
}, {
    underscored: true
}); 
module.exports = Movie;

Note:- Don't forget to create a movies table. https://github.com/ultimateakash/node-excel-csv/blob/master/node-excel-csv.sql

Above Schema Based on the import(excel or csv) file.

7. Install multer and uniqid npm packages.

npm i multer, uniqid

8. create a folder helpers and inside this folder create a file uploader.js

const multer = require('multer');
const uniqid = require('uniqid'); 
const path = require('path');

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, 'storage/uploads/')
    },
    filename: function(req, file, cb) {
        cb(null, Date.now() + uniqid() + path.extname(file.originalname))
    }
})
const upload = multer({ storage: storage });

exports.upload = (field) => upload.single(field); 

9. Create a storage folder and inside this create uploads and outputs folder.

10. Install xlsx npm package.

npm i xlsx

xlsx package provides a bunch of functions for reading and writing CSV/Excel files.

Parsing functions:-

      XLSX.read(data, read_opts) attempts to parse data

      XLSX.readFile(filename, read_opts) attempts to read filename and parse.

Note:- you can pass raw option to false  if you want formatted data.(example - formatted date)

XLSX.read(data, { raw: false })
XLSX.readFile(filename, { raw: false })

Writing functions:-

      XLSX.write(wb, write_opts) attempts to write the workbook

      XLSX.writeFile(wb, filename, write_opts) attempts to write workbook

Utility Functions:-

      Constructing:-

            book_new creates an empty workbook

            book_append_sheet adds a worksheet to a workbook

       Importing:

           aoa_to_sheet converts an array of arrays of JS data to a worksheet

           json_to_sheet converts an array of JS objects to a worksheet

          sheet_add_aoa adds an array of arrays of JS data to an existing worksheet.

          sheet_add_json adds an array of JS objects to an existing worksheet.

    Exporting:

          sheet_to_json converts a worksheet object to an array of JSON objects.

          sheet_to_csv generates delimiter-separated-values output.

Ref:- https://www.npmjs.com/package/xlsx

11. Create a folder controllers and inside this folder create movie.controller.js

controllers/movie.controller.js

const XLSX = require("xlsx"); 
const Movie = require("../models/movie.model")
const outputPath = 'storage/outputs' 

exports.index = async (req, res) => { 
    const movies = await Movie.findAll();
    return res.render('index', { movies });
}

exports.import = async (req, res) => { 
    const wb = XLSX.readFile(req.file.path); 
    const sheets = wb.SheetNames;
    
    if(sheets.length > 0) {
        const data = XLSX.utils.sheet_to_json(wb.Sheets[sheets[0]]);
        const movies = data.map(row => ({
            movie: row['Movie'],
            category: row['Category'],
            director: row['Director'],
            rating: row['Rating']
        }))
        await Movie.bulkCreate(movies); 
    }
    return res.redirect('/');
}

exports.export = async (req, res) => {
    const movies = await Movie.findAll({
        attributes: [
            'id', 
            'movie', 
            'category', 
            'director', 
            'rating'
        ],
        raw: true
    }); 

    const headings = [
        ['Id', 'Movie', 'Category', 'Director', 'Rating']
    ]; 

    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(movies, { 
        origin: 'A2', 
        skipHeader: true 
    });
    XLSX.utils.sheet_add_aoa(ws, headings); 
    XLSX.utils.book_append_sheet(wb, ws, 'Movies');

    const buffer = XLSX.write(wb, { bookType: 'csv', type: 'buffer' }); 
    res.attachment('movies.csv');

    return res.send(buffer);
}

Note:- In this article, I am using import file headers if your file doesn't have a headers row then you can use indexes.

You need to pass header option with sheet_to_json

const data = XLSX.utils.sheet_to_json(wb.Sheets[sheets[0]], { header: 1 });
const movies = data.map(row => ({
    movie: row[0],
    category: row[1],
    director: row[2],
    rating: row[3]
}))

In the above code you can change the extension based on the file you want to import or export. (.xlsx, .xls, .csv)

Note:- If want to store your exported file on the server you can use writeFile function.

const wb = XLSX.utils.book_new();
const ws = XLSX.utils.json_to_sheet(movies, { 
    origin: 'A2', 
    skipHeader: true 
});
XLSX.utils.sheet_add_aoa(ws, headings); 
XLSX.utils.book_append_sheet(wb, ws, 'Movies');

const filepath = `${outputPath}/movies.csv`;
XLSX.writeFile(wb, filepath); 

return res.download(filepath)

12. Create routes.

routes/index.js

const express = require('express');
const router = express.Router();
const movieController = require('../controllers/movie.controller');
const { upload } = require('../helpers/uploader');

router.get('/',                        movieController.index);
router.post('/import', upload('file'), movieController.import);
router.get('/export',                  movieController.export);

module.exports = router;

13. Open views/index.hbs and add the following code.

<main>
    <div class="row mb-2">
        <div class="col-sm-8 offset-2">
            <div class="row">
                <div class="col-md-6">
                    <form method="POST" action="/import" enctype="multipart/form-data"> 
                        <div class="input-group">
                            <div class="custom-file">
                                <input type="file" name="file" class="custom-file-input" id="inputGroupFile" required accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
                                <label class="custom-file-label" for="inputGroupFile">Choose file</label>
                            </div>
                            <div class="input-group-append">
                                <button type="submit" class="btn btn-primary float-right mr-2">Import <i class="fa fa-upload"></i></button>
                            </div>
                        </div>
                    </form>
                </div>
                <div class="col-md-6">
                    <a href="/export" class="btn btn-primary float-right {{#unless movies.length}} disabled {{/unless }}" role="button" aria-disabled="true">
                        Export <i class="fa fa-download"></i>
                    </a>
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-8 offset-2">
            <table class="table">
                <thead>
                    <tr>
                        <th scope="col">Id</th>
                        <th scope="col">Movie</th>
                        <th scope="col">Category</th>
                        <th scope="col">Director</th>
                        <th scope="col">Rating</th>
                    </tr>
                </thead>
                <tbody>
                    {{#each movies}} 
                        <tr>
                            <th scope="row">{{ this.id }}</th>
                            <td>{{ this.movie }}</td>
                            <td>{{ this.category }}</td>
                            <td>{{ this.director }}</td>
                            <td><span class="badge bg-warning text-dark">{{ this.rating }}</span></td>
                        </tr>
                    {{else}}
                        <tr>
                            <td colspan="5" class="text-center">No Movies Found.</td>
                        </tr>
                    {{/each}}  
                </tbody>
            </table>
        </div>
    </div>
</main>

Note:- please checkout github repo - https://github.com/ultimateakash/node-excel-csv

14. Finally start the project.

npm start

Open http://localhost:3000 and try import and export.

Extras:- if you want to read a file without uploading then you can use multer.memoryStorage()

const multer = require('multer'); 
const upload = multer({ storage: multer.memoryStorage() });
exports.upload = (field) => upload.single(field);

with memoryStorage() you can access the file buffer.

const wb = XLSX.read(req.file.buffer); 
const sheets = wb.SheetNames;

 

Sample Excel CSV Files:- https://github.com/ultimateakash/node-excel-csv/tree/master/sample%20files

Checkout my full node-excel-csv example. https://github.com/ultimateakash/node-excel-csv

If you facing any issues. don't hesitate to comment below. I will be happy to help you.

Thanks.

Leave Your Comment