This repository contains my custom ExcelJS functions to facilitate exporting HTML tables to Excel with styling and merged cell support directly from HTML structure and CSS.
-
Multiple Table Export in One Sheet
Export multiple HTML tables to a single worksheet by providing a class name. -
Automatic Cell Merging
Handlesrowspanandcolspanusing ExcelJS cell merging. -
Dynamic Column Widths
Automatically calculates and sets appropriate column widths based on content. -
Text Wrapping & Line Breaks
Supports<br>tags by converting them to\nand enablingwrapText.
-
Custom Cell Styling
Applies styles such as:- Background color (cascades from cell → row → section)
- Font color and size
- Bold (from computed style or presence of
<b>/<strong>) - Vertical/horizontal alignment (
.text-center,.text-right) - Text rotation (from CSS
transformorwriting-mode) - Borders for all cells
-
Partial Bold Support
Inline<b>and<strong>tags inside cells are rendered as bold using ExcelJSrichText, without overriding existing styles. -
Number & Percentage Formatting
- Detects numeric values and applies comma-separated formatting (
#,##0.00) - Automatically formats percentages (e.g.,
25%becomes0.25with Excel%format)
- Detects numeric values and applies comma-separated formatting (
-
Row Grouping & Collapse Support
Use HTML classes to control outline/grouping levels:<tr class="collapse">→ grouped and hidden<tr class="collapse in">→ grouped and visible<tr class="collapse-level-2">→ grouped at level 2<tr class="hidden">→ row will be hidden
-
Hidden Columns Based on Headers
- Add
.hide-columnto any<th>element in<thead> - Supports complex multi-row headers with
colspanandrowspan
- Add
git clone https://github.com/niwayandm/ExcelJS-Custom.git<script src="path/to/CustomExport.js"></script>Ensure you have ExcelJS included in your project as well:
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.2.0/exceljs.min.js"></script><table class="exportTable">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>10</td>
<td>2.50</td>
</tr>
<tr>
<td>Banana</td>
<td>5</td>
<td>1.20</td>
</tr>
</tbody>
</table>
<button onclick="exportToExcel()">Export to Excel</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.2.0/exceljs.min.js"></script>
<script src="path/to/CustomExport.js"></script>
<script>
async function exportToExcel() {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Inventory');
exportTableToWorksheet('exportTable', worksheet);
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'Inventory.xlsx';
link.click();
}
</script>Example with hidden columns and row grouping
<table class="exportTable">
<thead>
<tr>
<th class="hide-column">Internal Code</th>
<th>Item</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>X123</td>
<td><b>Apple</b></td>
<td>1.00</td>
</tr>
<tr class="collapse">
<td>X124</td>
<td><b>Banana</b></td>
<td>0.50</td>
</tr>
</tbody>
</table>
<button onclick="exportToExcel()">Export to Excel</button>
<script>
// Setup workbook, wait for table, export
</script><table class="exportTable">
<thead>
<tr>
<th rowspan="2">Product</th>
<th colspan="2">Q1 Sales</th>
</tr>
<tr>
<th>Volume</th>
<th>Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>120</td>
<td>$2400</td>
</tr>
<tr>
<td>Banana</td>
<td>200</td>
<td>$3000</td>
</tr>
</tbody>
</table>
<button onclick="exportToExcel()">Export to Excel</button>
<script>
// Setup workbook, wait for table, export
</script>| Function | Description |
|---|---|
delay(ms) |
Returns a promise that resolves after a delay |
getColumnAddress(colNum) |
Converts a column number (1 → A, 27 → AA) |
columnToNumber(column) |
Converts column letters to numeric index |
setCellStyle(htmlCell, excelCell) |
Applies background, font, alignment, borders |
getColSpan(worksheet, cellA ddress, rowNumber) |
Returns the colspan for a merged cell |
getMaxRow(worksheet) |
Returns the last used row number |
isTopLeftCellOfMerge(worksheet, cellAddress) |
Checks if a cell is the top-left in a merged range |
exportTableToWorksheet(tableClassName, worksheet, startRow = 0, excludeNumberFormatting = []) |
Main function to export an HTML table to an Excel sheet |
waitForTableLoad(tableId) |
Asynchronously waits for a table to be present in DOM |
Thanks to the ExcelJS team for their outstanding open-source library!