- πͺ Transform Excel & CSV files into JSON with advanced features
- π¦ Lightweight library with minimal dependencies
- π Support for Google online Excel files (URLs)
- π Handle multiple sheets with ease
- π Smart date formatting
- β‘ Async API with streaming support for large files
npm i excel-to-json.mlaior
yarn add excel-to-json.mlaior
pnpm i excel-to-json.mlai- β Convert Excel files (.xlsx, .xls) to JSON
- β Convert CSV files to JSON π
- β Support for multiple sheets
- β Fetch and convert online Excel files (including Google Sheets)
- β Customizable date formatting
- β Header transformation
- β Value transformation
- β Skip empty rows/columns
- β Formula support
- β Nested objects from dot-notation columns π
- β TypeScript support
import { excelToJson } from 'excel-to-json.mlai';
// Convert Excel file
const data = await excelToJson('path/to/file.xlsx');
console.log(data);
// Output: [{name: 'John', age: 30}, {name: 'Jane', age: 25}, ...]
// Convert CSV file (automatically detected)
const csvData = await excelToJson('path/to/file.csv');
console.log(csvData);
// Output: [{name: 'John', age: 30}, {name: 'Jane', age: 25}, ...]// Get all sheets
const allSheets = await excelToJson('file.xlsx', { sheets: 'all' });
console.log(allSheets);
// Output: { Sheet1: [...], Sheet2: [...], Sheet3: [...] }
// Get specific sheets
const specificSheets = await excelToJson('file.xlsx', {
sheets: ['Sales', 'Inventory']
});// Convert from URL
const onlineData = await excelToJson('https://example.com/data.xlsx');
// Google Sheets support
const sheetsData = await excelToJson('https://docs.google.com/spreadsheets/d/your-sheet-id/edit');
// Online CSV files
const csvData = await excelToJson('https://example.com/data.csv');Automatically detects and parses CSV files with customizable options:
// Basic CSV conversion
const data = await excelToJson('data.csv');
// CSV with custom delimiter and options
const data = await excelToJson('data.csv', {
csvDelimiter: ';', // Custom delimiter (auto-detected by default)
csvQuote: '"', // Quote character
csvEscape: '"', // Escape character
nestedObj: true, // Create nested objects
transformValue: (v, h) => {
// Transform values
if (h === 'price') return parseFloat(v);
return v;
}
});Transform flat columns with dot notation into nested objects:
// Excel columns: name, age, hobbies.0, hobbies.1, hobbies.2, address.street, address.city
const data = await excelToJson('file.xlsx', {
nestedObj: true
});
// Input (flat):
// { name: 'John', 'hobbies.0': 'Reading', 'hobbies.1': 'Gaming', 'address.street': '123 Main St' }
// Output (nested):
// {
// name: 'John',
// hobbies: { '0': 'Reading', '1': 'Gaming' },
// address: { street: '123 Main St' }
// }const data = await excelToJson('file.xlsx', {
dateFormat: 'YYYY-MM-DD' // or 'DD/MM/YYYY', 'MM-DD-YYYY', etc.
});const data = await excelToJson('file.xlsx', {
// Transform headers to lowercase with underscores
transformHeader: (header) => header.toLowerCase().replace(/\s+/g, '_'),
// Transform values
transformValue: (value, header) => {
if (header === 'price') return parseFloat(value);
if (header === 'active') return value === 'yes';
return value;
}
});const data = await excelToJson('file.xlsx', {
sheetSelection: ['Sheet1', 'Sheet2'], // Specific sheets (or 'all', 'first')
dateFormatPattern: 'DD/MM/YYYY', // Date format
shouldSkipEmptyRows: true, // Skip empty rows
shouldSkipEmptyColumns: true, // Skip empty columns
hasHeaderRow: true, // Use first row as headers
headerRowIndex: 1, // Headers on row 2 (0-based)
shouldIncludeSheetName: true, // Add _sheet property to each row
shouldParseFormulas: true, // Parse formula results
shouldCreateNestedObjects: false, // Create nested objects from dot-notation
csvParsingOptions: { // CSV parsing options
fieldDelimiter: ',', // CSV delimiter (auto-detected)
quoteCharacter: '"', // CSV quote character
escapeCharacter: '"' // CSV escape character
},
headerTransformer: (h) => h.trim(), // Clean headers
valueTransformer: (v, h) => v // Process values
});import { excelToJson } from 'excel-to-json.mlai';
// Async processing for all files
const data = await excelToJson('path/to/file.xlsx');Asynchronously converts Excel or CSV file to JSON.
Parameters:
input(string | ArrayBuffer | Buffer): File path, URL, or buffer (supports .xlsx, .xls, .csv)options(SpreadsheetConversionConfig): Optional configuration
Returns: Promise<Record<string, any>[] | Record<string, Record<string, any>[]>>
interface SpreadsheetConversionConfig {
sheetSelection?: 'all' | 'first' | string[] | number[];
dateFormatPattern?: string;
shouldSkipEmptyRows?: boolean;
shouldSkipEmptyColumns?: boolean;
headerTransformer?: (header: string) => string;
valueTransformer?: (value: any, header: string) => any;
hasHeaderRow?: boolean;
headerRowIndex?: number;
shouldIncludeSheetName?: boolean;
shouldParseFormulas?: boolean;
shouldCreateNestedObjects?: boolean; // π Create nested objects from dot-notation
csvParsingOptions?: CsvParsingConfiguration; // π CSV parsing options
}const salesData = await excelToJson('sales-2024.xlsx', {
sheets: ['Q1', 'Q2', 'Q3', 'Q4'],
dateFormat: 'MM/DD/YYYY',
transformHeader: (h) => h.toLowerCase().replace(/\s+/g, '_'),
transformValue: (v, h) => {
if (h === 'revenue' || h === 'cost') {
return parseFloat(v.replace(/[$,]/g, ''));
}
return v;
}
});const employees = await excelToJson('https://hr.company.com/employees.xlsx', {
skipEmptyRows: true,
transformValue: (v, h) => {
if (h === 'Email') return v.toLowerCase();
if (h === 'Active') return v === 'Yes';
if (h === 'Salary') return parseFloat(v);
return v;
}
});// CSV file with columns: name, age, hobbies.0, hobbies.1, hobbies.2, skills.programming.0
const csvData = await excelToJson('employees.csv', {
nestedObj: true,
transformValue: (v, h) => {
// Convert boolean strings
if (v === 'TRUE' || v === 'yes') return true;
if (v === 'FALSE' || v === 'no') return false;
// Convert numbers
if (h === 'salary' && !isNaN(Number(v))) return Number(v);
return v;
}
});
// Result:
// {
// name: 'John',
// age: 25,
// hobbies: { '0': 'Reading', '1': 'Gaming' },
// skills: { programming: { '0': 'JavaScript' } },
// salary: 60000
// }// Excel columns: name, age, skills.programming.0, skills.programming.1, hobbies.0, hobbies.1
const surveyData = await excelToJson('survey.xlsx', {
nestedObj: true,
transformValue: (v, h) => {
// Convert boolean-like strings
if (v === 'TRUE' || v === 'yes') return true;
if (v === 'FALSE' || v === 'no') return false;
return v;
}
});
// Result:
// {
// name: 'John',
// age: 25,
// skills: {
// programming: { '0': 'JavaScript', '1': 'Python' }
// },
// hobbies: { '0': 'Reading', '1': 'Gaming' }
// }const analysis = await excelToJson('data.xlsx', {
sheets: 'all',
includeSheetName: true,
dateFormat: 'YYYY-MM-DD'
});
// Process each sheet
for (const [sheetName, data] of Object.entries(analysis)) {
console.log(`Processing ${sheetName}: ${data.length} rows`);
}Now supports CSV files with automatic detection and parsing:
// Works with both Excel and CSV files
const excelData = await excelToJson('data.xlsx');
const csvData = await excelToJson('data.csv');
// CSV with custom options
const data = await excelToJson('data.csv', {
csvDelimiter: ';',
nestedObj: true
});Transform flat columns with dot notation into nested object structures:
// Excel with columns: name, hobbies.0, hobbies.1, address.street, address.city
const data = await excelToJson('file.xlsx', { shouldCreateNestedObjects: true });
// Before (flat):
{
name: 'John',
'hobbies.0': 'Reading',
'hobbies.1': 'Gaming',
'address.street': '123 Main St',
'address.city': 'New York'
}
// After (nested):
{
name: 'John',
hobbies: {
'0': 'Reading',
'1': 'Gaming'
},
address: {
street: '123 Main St',
city: 'New York'
}
}- π Full CSV file support with auto-detection
- π Improved Google Sheets support
- π§ Better TypeScript definitions
- β‘ Performance optimizations
- π Bug fixes for edge cases
The new version includes breaking changes:
// Old (v0.x)
import { excelToJson } from 'excel-to-json.mlai';
const data = excelToJson('file.xlsx'); // Synchronous, single sheet
// New (v1.0+)
import { excelToJson } from 'excel-to-json.mlai';
const data = await excelToJson('file.xlsx'); // Async by default// Excel columns: name, price, variants.size.0, variants.size.1, variants.color.0, variants.color.1
const products = await excelToJson('products.xlsx', {
nestedObj: true,
transformValue: (v, h) => {
if (h === 'price') return parseFloat(v);
return v;
}
});
// Result:
// {
// name: 'T-Shirt',
// price: 19.99,
// variants: {
// size: { '0': 'S', '1': 'M', '2': 'L' },
// color: { '0': 'Red', '1': 'Blue' }
// }
// }// CSV columns: date, product, revenue, cost, region
const salesData = await excelToJson('sales.csv', {
transformValue: (v, h) => {
// Parse currency values
if (h === 'revenue' || h === 'cost') {
return parseFloat(v.replace(/[$,]/g, ''));
}
// Parse dates
if (h === 'date') {
return new Date(v);
}
return v;
}
});// Excel columns: userId, preferences.notifications.email, preferences.notifications.sms, preferences.theme
const userPrefs = await excelToJson('user-preferences.xlsx', {
nestedObj: true,
transformValue: (v, h) => {
// Convert boolean strings
if (v === 'yes' || v === 'true') return true;
if (v === 'no' || v === 'false') return false;
return v;
}
});
// Result:
// {
// userId: 'user123',
// preferences: {
// notifications: {
// email: true,
// sms: false
// },
// theme: 'dark'
// }
// }- Use specific sheets: Instead of
sheetSelection: 'all', specify only needed sheets - Skip empty data: Enable
shouldSkipEmptyRowsandshouldSkipEmptyColumnsfor faster processing - Minimize transformations: Complex transformations can slow down large files
- Nested objects: Use
shouldCreateNestedObjects: trueonly when needed, as it adds processing overhead - Streaming for large files: Enable streaming mode for very large files
- Batch processing: For very large files, consider processing in chunks
All contributions are welcome! Please read our contributing guidelines.
excel-to-json.mlai is MIT licensed.