feat: support WPS report material workbooks

This commit is contained in:
hectorzhao
2026-09-04 17:10:04 +08:00
parent 48d0363920
commit fb39c8b606
29 changed files with 2737 additions and 734 deletions
@@ -0,0 +1,42 @@
import ExcelJS from 'exceljs';
import JSZip from 'jszip';
import { compatibleImages, convertWorkbookOutput, loadCompatibleWorkbook } from './workbook-compatibility';
const PNG = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9Y9ZrYQAAAAASUVORK5CYII=',
'base64',
);
async function standardWorkbook() {
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('签名报备');
sheet.getCell('A1').value = '营业执照';
sheet.getCell('A2').value = 'license.png';
const imageId = workbook.addImage({ buffer: PNG as never, extension: 'png' });
sheet.addImage(imageId, { tl: { col: 0, row: 1 }, br: { col: 0.9, row: 1.9 }, editAs: 'oneCell' } as never);
return Buffer.from(await workbook.xlsx.writeBuffer());
}
describe('WPS workbook compatibility', () => {
it('converts a standard Drawing image to DISPIMG and reads it back from cellimages.xml', async () => {
const converted = await convertWorkbookOutput(await standardWorkbook(), 'wps_cell_image');
const zip = await JSZip.loadAsync(converted);
await expect(zip.file('xl/cellimages.xml')!.async('string')).resolves.toContain('ID_');
const loaded = await loadCompatibleWorkbook(converted);
const images = compatibleImages(
loaded.workbook,
loaded.workbook.getWorksheet('签名报备')!,
loaded.wpsImagesBySheet,
);
expect(images).toHaveLength(1);
expect(images[0]).toMatchObject({ row: 2, column: 1, extension: 'png' });
expect(images[0].buffer.equals(PNG)).toBe(true);
});
it('still rejects ordinary formulas instead of weakening spreadsheet safety', async () => {
const workbook = new ExcelJS.Workbook();
workbook.addWorksheet('危险').getCell('A1').value = { formula: 'HYPERLINK("https://example.com")' };
const content = Buffer.from(await workbook.xlsx.writeBuffer());
await expect(loadCompatibleWorkbook(content)).rejects.toThrow('不允许的公式');
});
});