diff --git a/custom_addons/dashboard/static/src/components/pqgrid_dashboard/pqgrid_stock_dashboard.js b/custom_addons/dashboard/static/src/components/pqgrid_dashboard/pqgrid_stock_dashboard.js
index 3629ae813..847b9061d 100644
--- a/custom_addons/dashboard/static/src/components/pqgrid_dashboard/pqgrid_stock_dashboard.js
+++ b/custom_addons/dashboard/static/src/components/pqgrid_dashboard/pqgrid_stock_dashboard.js
@@ -439,85 +439,68 @@ export class StockDashboard extends Component {
this.downloadFile(csvContent, fileName, 'text/csv');
}
- exportToExcel() {
- let tableHeaders, rows;
+ async exportToExcel() {
+ // Load SheetJS library dynamically if not available
+ if (typeof XLSX === 'undefined') {
+ await new Promise((resolve, reject) => {
+ const script = document.createElement('script');
+ script.src = 'https://cdn.sheetjs.com/xlsx-0.20.1/package/dist/xlsx.full.min.js';
+ script.onload = resolve;
+ script.onerror = reject;
+ document.head.appendChild(script);
+ });
+ }
+
+ let headers, data;
if (this.state.activeCategory === 'Finished Products') {
const filteredData = this.getFilteredFinishedProducts();
- tableHeaders = `
-
- | Product Code |
- Product Name |
- Opening Stock |
- Production |
- Dispatch |
- Closing Stock |
- UOM |
- Value |
-
- `;
- rows = filteredData.map(row => `
-
- | ${row.product_code || ''} |
- ${row.product_name || ''} |
- ${row.opening_stock || 0} |
- ${row.production || 0} |
- ${row.dispatch || 0} |
- ${row.closing_stock || 0} |
- ${row.uom || ''} |
- ${row.value || 0} |
-
- `).join('');
+ headers = ['Product Code', 'Product Name', 'Opening Stock', 'Production', 'Dispatch', 'Closing Stock', 'UOM', 'Value'];
+ data = filteredData.map(row => [
+ row.product_code || '',
+ row.product_name || '',
+ row.opening_stock || 0,
+ row.production || 0,
+ row.dispatch || 0,
+ row.closing_stock || 0,
+ row.uom || '',
+ row.value || 0
+ ]);
} else {
const filteredData = this.getFilteredRawMaterials();
- tableHeaders = `
-
- | Product Code |
- Product Name |
- Opening Stock |
- Receipts |
- Consumption |
- Closing Stock |
- UOM |
- Value |
-
- `;
- rows = filteredData.map(row => `
-
- | ${row.product_code || ''} |
- ${row.product_name || ''} |
- ${row.opening_stock || 0} |
- ${row.receipts || 0} |
- ${row.consumption || 0} |
- ${row.closing_stock || 0} |
- ${row.uom || ''} |
- ${row.value || 0} |
-
- `).join('');
+ headers = ['Product Code', 'Product Name', 'Opening Stock', 'Receipts', 'Consumption', 'Closing Stock', 'UOM', 'Value'];
+ data = filteredData.map(row => [
+ row.product_code || '',
+ row.product_name || '',
+ row.opening_stock || 0,
+ row.receipts || 0,
+ row.consumption || 0,
+ row.closing_stock || 0,
+ row.uom || '',
+ row.value || 0
+ ]);
}
- const tableHtml = `
-
-
-
-
-
-
- ${this.state.activeCategory} Report - ${this.state.fromDate} to ${this.state.toDate}
-
- ${tableHeaders}
- ${rows}
-
-
-
- `;
+ // Create workbook and worksheet
+ const wb = XLSX.utils.book_new();
+ const ws = XLSX.utils.aoa_to_sheet([headers, ...data]);
- const fileName = `${this.state.activeCategory.toLowerCase().replace(/ /g, '-')}_${this.state.fromDate}_to_${this.state.toDate}.xls`;
- this.downloadFile(tableHtml, fileName, 'application/vnd.ms-excel');
+ // Set column widths
+ const colWidths = headers.map((header, idx) => {
+ const maxLength = Math.max(
+ header.length,
+ ...data.map(row => String(row[idx] || '').length)
+ );
+ return { wch: Math.min(maxLength + 2, 50) };
+ });
+ ws['!cols'] = colWidths;
+
+ // Add worksheet to workbook
+ XLSX.utils.book_append_sheet(wb, ws, this.state.activeCategory);
+
+ // Generate XLSX file
+ const fileName = `${this.state.activeCategory.toLowerCase().replace(/ /g, '-')}_${this.state.fromDate}_to_${this.state.toDate}.xlsx`;
+ XLSX.writeFile(wb, fileName);
}
exportToJSON() {