/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const htmlStr = (): unknown => {
const html_start =
'';
return {
uri: 'data:application/vnd.ms-excel;base64,',
template_ExcelWorksheet:
'{SheetName} ',
template_ListWorksheet: ' ',
template_WorkBook:
`MIME-Version: 1.0
X-Document-Type: Workbook
Content-Type: multipart/related; boundary="----=_NextPart_dummy"
------=_NextPart_dummy
Content-Location: WorkBook.htm
Content-Type: text/html; charset=windows-1252
` +
html_start +
`
This page uses frames, but your browser does not support them.
{HTMLWorksheets}
Content-Location: filelist.xml
Content-Type: text/xml; charset="utf-8"
{ListWorksheets}
------=_NextPart_dummy--
`,
};
};
export class ExcelFormater {
static tmplCellXML = '{data} | ';
static base64 = function (s: unknown): string {
//@ts-ignore
return window.btoa(unescape(encodeURIComponent(s)));
};
static format(s: unknown, c: unknown): string {
//@ts-ignore
return s.replace(/{(\w+)}/g, function (m: unknown, p: unknown) {
//@ts-ignore
return c[p];
});
}
static createExcelRow(columns: unknown[], data: unknown): string {
let rowsXML = '';
rowsXML += '';
for (let k = 0; k < columns.length; k++) {
//@ts-ignore
let dataIndex = columns[k].getAttribute('data-index'); //@ts-ignore
let columnName = columns[k].getAttribute('title');
if (columnName === '') {
columnName = dataIndex;
}
let ctx = {
attributeStyleID: '',
nameType: 'String', //@ts-ignore
data: data ? data[dataIndex] || '' : columnName,
attributeFormula: '',
};
rowsXML += this.format(this.tmplCellXML, ctx);
}
rowsXML += '
'; //@ts-ignore
if (data && data.children !== undefined && data.children.length > 0) {
//@ts-ignore
data.children.forEach((child: unknown) => {
rowsXML += this.createExcelRow(columns, child);
});
}
return rowsXML;
}
static addImage(baseStr: string): string {
return `${this.format(this.tmplCellXML, {
attributeStyleID: '',
nameType: 'String',
data: ``,
attributeFormula: '',
})}
`;
}
static testExport(
dataSource: { columns: unknown[]; tables: unknown[]; sheetName: string }[],
fileName: string
): void {
this.tablesToHtmlExcelMultipleSheet(dataSource, fileName);
}
static tablesToHtmlExcelMultipleSheet(
dataSource: { columns: unknown[]; tables: unknown[]; sheetName: string }[],
fileName: string,
image?: string
): void {
let sheets: unknown[] = [];
dataSource.forEach((data): void => {
sheets.push(this.createTableData(data.columns, data.tables, image));
});
this.tablesToExcelTestSheet(sheets, fileName, dataSource);
}
static createTableData(columns: unknown[], dataSource: unknown[], image?: string): string {
let tableData = '';
let columnDatas = columns.map((column) => {
//@ts-ignore
let dataIndex = column.getAttribute('data-index'); //@ts-ignore
let columnName = column.getAttribute('title');
if (columnName === '') {
columnName = dataIndex;
}
return {
columnName: columnName,
dataIndex: dataIndex,
};
});
tableData += this.createTHead(
columnDatas.map((item) => {
return item.columnName;
})
);
let columnDataIndexes = columnDatas.map((item) => item.dataIndex);
dataSource.forEach((data, index) => {
if (index === 0 && image) {
tableData += this.createTableRow(columnDataIndexes, data, image);
} else {
tableData += this.createTableRow(columnDataIndexes, data);
}
});
return tableData;
}
static createTHead(columns: unknown[]): string {
let header = '';
columns.forEach((column) => {
header += `${column} `;
});
header += '';
return header;
}
static createTableRow(columns: unknown[], data: unknown, image?: unknown): string {
let childrenData = ''; //@ts-ignore
if (data.children !== undefined) {
//@ts-ignore
data.children.forEach((child: unknown) => {
if (child) {
childrenData += this.createTableRow(columns, child);
}
});
}
return `${columns
.map((column) => {
//@ts-ignore
return `${(data[column] + '').replace('μ', 'u')} ` || '';
})
.join('')}${image ? ` ` : ''} ${childrenData}`;
}
static tablesToExcelTestSheet(
tables: unknown[],
filename: string,
dataSource: { columns: unknown[]; tables: unknown[]; sheetName: string }[]
): void {
const html_start =
''; //@ts-ignore
let { uri, template_ExcelWorksheet, template_ListWorksheet, template_WorkBook } = htmlStr();
let template_HTMLWorksheet =
`
------=_NextPart_dummy
Content-Location: sheet{SheetIndex}.htm
Content-Type: text/html; charset=windows-1252
` +
html_start +
`
`;
let context_WorkBook = {
ExcelWorksheets: '',
HTMLWorksheets: '',
ListWorksheets: '',
};
tables.forEach((item, sheetIndex) => {
context_WorkBook.ExcelWorksheets += this.format(template_ExcelWorksheet, {
SheetIndex: sheetIndex,
SheetName: dataSource[sheetIndex].sheetName,
});
context_WorkBook.HTMLWorksheets += this.format(template_HTMLWorksheet, {
SheetIndex: sheetIndex,
SheetContent: item,
});
context_WorkBook.ListWorksheets += this.format(template_ListWorksheet, {
SheetIndex: sheetIndex,
});
});
let link = document.createElement('a');
link.href = uri + this.base64(this.format(template_WorkBook, context_WorkBook));
link.download = filename + '.xls';
link.target = '_blank';
link.click();
}
}