Exporting JSON Data to Excel or CSV in the Browser
Front end developers often need to allow users to export tabular data directly from the browser. Below are two common approaches using only JavaScript—exporting as a pseudo-Excel (.xls) file via HTML tables, and exporting as a CSV file.
Method 1: Export as Excel (.xls) Using HTML Table Markup
This technique wraps an HTML table inside an XML-based Excel template and encodes it in Base64. While the file has an .xls extension, it's actually HTML formatted to be recognized by Excel.
<button onclick="exportToExcel()">Export to Excel</button>
<script>
function exportToExcel() {
const records = [
{ name: 'Alice', phone: '5551234', email: 'alice@example.com' },
{ name: 'Bob', phone: '5555678', email: 'bob@example.com' },
{ name: 'Charlie', phone: '5559012', email: 'charlie@example.com' }
];
let tableContent = '<tr><th>Name</th><th>Phone</th><th>Email</th></tr>';
records.forEach(row => {
tableContent += '<tr>';
Object.values(row).forEach(cell => {
// Append \t to prevent scientific notation in Excel
tableContent += `<td>${cell}\t</td>`;
});
tableContent += '</tr>';
});
const worksheetName = 'DataSheet';
const template = `
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<!--[if gte mso 9]>
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>${worksheetName}</x:Name>
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
<![endif]-->
</head>
<body>
<table>${tableContent}</table>
</body>
</html>`;
const uri = 'data:application/vnd.ms-excel;base64,';
const encoded = btoa(unescape(encodeURIComponent(template)));
window.location.href = uri + encoded;
}
</script>
Method 2: Export as CSV Using Data URI
This method constructs a comma-separated string and triggers a downlaod using a dynamically created anchor tag. It supports UTF-8 encoding and avoids scientific notation by appending a tab character.
<button onclick="exportToCSV()">Export to CSV</button>
<script>
function exportToCSV() {
const data = [
{ name: 'Diana', phone: '5553333', email: 'diana@test.org' },
{ name: 'Eve', phone: '5554444', email: 'eve@test.org' }
];
let csvContent = 'Name,Phone,Email\n';
data.forEach(row => {
const values = Object.values(row).map(value => `"${value}\t"`);
csvContent += values.join(',') + '\n';
});
const blob = new Blob(['\ufeff', csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', 'exported_data.csv');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
</script>
Preserving Table Styles When Exporting to Excel
To retain visual formatting (e.g., background color, font size), styles must be embedded directly in the exported HTML template. Excel does not respect external or page-level CSS.
Approach A: Inline Styles in Table Cells
Apply styles directly to <td> elements:
<td style="background-color: #4f891e; color: white; font-size: 18px; text-align: center;">Company A</td>
Approach B: Embed CSS in the Excel Template
Include a <style> block within the HTML template used for export:
const excelTemplate = `
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<!--[if gte mso 9]>...<![endif]-->
<style type="text/css">
table td {
border: 1px solid #000;
width: 200px;
height: 30px;
text-align: center;
background-color: #4f891e;
color: #ffffff;
font-size: 12px;
}
</style>
</head>
<body>
<table>{table}</table>
</body>
</html>`;
Note: If both inline styles and embedded CSS are present, inline styles take precedence.
The final export function replaces placeholders like {table} and {worksheet} with actual content and sheet name, then sets the download link’s href to the Base64-encoded result.