import { describe, expect, test, beforeEach, it, assert } from 'vitest' import * as XLSX from 'xlsx'; import ExcellentExport, { ConvertOptions, SheetOptions } from '../src/excellentexport'; describe('convert() API', function() { describe('convert from HTML table', function() { beforeEach(() => { window.URL.createObjectURL = () => "blob:fake_URL"; document.body.innerHTML = ''; const element = document.createElement("div"); element.innerHTML = '
firstsecond
1234123.56
' + 'Link'; document.body.appendChild(element); }); test('should create a XLSX from HTML table by #id', function() { const options = { anchor: 'anchor', filename: 'data_from_table', format: 'xlsx' } as ConvertOptions; const sheets = [ { name: 'Sheet Name Here 1', from: { table: 'sometable' } } ] as SheetOptions[]; const workbook = ExcellentExport.convert(options, sheets); expect(workbook).not.toBeNull(); const anchor = document.getElementById('anchor') as HTMLAnchorElement; expect(anchor.href).not.toBeNull(); expect(anchor.href).toMatch(/blob:/); }); test('should create a XLSX from HTML table by DOM element', function() { const options = { anchor: document.getElementById('anchor'), filename: 'data_from_table', format: 'xlsx' } as ConvertOptions; const sheets = [ { name: 'Sheet Name Here 1', from: { table: document.getElementById('sometable') } } ] as SheetOptions[]; const workbook = ExcellentExport.convert(options, sheets); expect(workbook).not.toBeNull(); const anchor = document.getElementById('anchor') as HTMLAnchorElement; expect(anchor.href).not.toBeNull(); expect(anchor.href).toMatch(/blob:/); }); }); describe('convert from HTML table with colspan and rowspan', function() { beforeEach(() => { window.URL.createObjectURL = () => "blob:fake_URL"; document.body.innerHTML = ''; const div = document.createElement('div'); div.innerHTML = 'Link'; document.body.appendChild(div); }); function buildWorksheet(tableHtml: string): XLSX.WorkSheet { const div = document.createElement('div'); div.id = 'wrapper'; div.innerHTML = tableHtml; document.body.appendChild(div); const wbBinary = ExcellentExport.convert( { anchor: 'anchor', filename: 'test', format: 'xlsx' } as ConvertOptions, [{ name: 'Sheet1', from: { table: div.querySelector('table') as HTMLTableElement } }] as SheetOptions[] ); const wb = XLSX.read(wbBinary, { type: 'binary' }); return wb.Sheets['Sheet1']; } test('should produce merged cells for colspan=2', function() { const ws = buildWorksheet( '' + '' + '' + '
Header
AB
' ); // Cell A1 should contain "Header" expect(ws['A1'].v).toBe('Header'); // Merged region should cover A1:B1 expect(ws['!merges']).toBeDefined(); expect(ws['!merges']).toHaveLength(1); expect(ws['!merges']![0]).toEqual({ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }); }); test('should produce merged cells for rowspan=2', function() { const ws = buildWorksheet( '' + '' + '' + '
SideTop
Bottom
' ); expect(ws['A1'].v).toBe('Side'); expect(ws['B1'].v).toBe('Top'); expect(ws['B2'].v).toBe('Bottom'); expect(ws['!merges']).toBeDefined(); expect(ws['!merges']).toHaveLength(1); expect(ws['!merges']![0]).toEqual({ s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }); }); test('should produce merged cells for combined colspan=2 rowspan=2', function() { const ws = buildWorksheet( '' + '' + '' + '' + '
BigR0C2
R1C2
R2C0R2C1R2C2
' ); expect(ws['A1'].v).toBe('Big'); expect(ws['C1'].v).toBe('R0C2'); expect(ws['C2'].v).toBe('R1C2'); expect(ws['A3'].v).toBe('R2C0'); expect(ws['!merges']).toBeDefined(); expect(ws['!merges']).toHaveLength(1); expect(ws['!merges']![0]).toEqual({ s: { r: 0, c: 0 }, e: { r: 1, c: 1 } }); }); test('should produce no merges for a table without spans', function() { const ws = buildWorksheet( '' + '' + '' + '
AB
CD
' ); expect(ws['A1'].v).toBe('A'); expect(ws['B2'].v).toBe('D'); // No merges const merges = ws['!merges']; expect(merges ?? []).toHaveLength(0); }); }); });