@sd-angular/core
Version:
Sd Angular Core Lib
505 lines (500 loc) • 24.1 kB
JavaScript
import { FIREBASE_CONFIG } from '@sd-angular/core/common';
import { __classPrivateFieldGet, __awaiter } from 'tslib';
import { ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, Optional } from '@angular/core';
import { SdApiService } from '@sd-angular/core/api';
import { v4 } from 'uuid';
import hash from 'object-hash';
import { ExportToCsv } from 'export-to-csv';
import { Workbook } from 'exceljs';
import { SdNotifyService } from '@sd-angular/core/notify';
const API = {
uploadTemplate: '/excel/uploadTemplate',
generateUploadTemplate: '/excel/generateUploadTemplate',
filesInFolder: '/excel/filesInFolder',
removeFile: '/excel/remove',
sdExportByTemplate: '/excel/sd-export-by-template',
sdMergePDF: '/excel/sd-merge-pdf',
};
var _fieldStyle, _titleColor, _titleFgColor, _titleStyle, _requiredStyle, _descriptionStyle, _cellStyle, _directory;
class SdExportService {
constructor(apiService, notifyService, firebaseConfiguration) {
this.apiService = apiService;
this.notifyService = notifyService;
this.firebaseConfiguration = firebaseConfiguration;
_fieldStyle.set(this, {
border: {
bottom: { style: 'thin' },
left: { style: 'thin' },
right: { style: 'thin' },
},
alignment: {
vertical: 'middle',
horizontal: 'center',
wrapText: true,
},
font: {
bold: true,
size: 11,
color: { argb: '000000' },
},
fill: {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: 'FAFAFA',
},
},
});
_titleColor.set(this, 'FFFFFF');
_titleFgColor.set(this, '143180');
_titleStyle.set(this, {
border: {
bottom: { style: 'thin' },
left: { style: 'thin' },
right: { style: 'thin' },
},
alignment: {
vertical: 'middle',
horizontal: 'center',
wrapText: true,
},
font: {
bold: true,
size: 11,
color: { argb: __classPrivateFieldGet(this, _titleColor) },
},
fill: {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: __classPrivateFieldGet(this, _titleFgColor),
},
},
});
_requiredStyle.set(this, {
border: {
bottom: { style: 'thin' },
left: { style: 'thin' },
right: { style: 'thin' },
},
alignment: {
vertical: 'middle',
horizontal: 'center',
wrapText: true,
},
font: {
italic: true,
size: 11,
color: { argb: 'FFFFFF' },
},
fill: {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: 'FF1744',
},
},
});
_descriptionStyle.set(this, {
border: {
bottom: { style: 'thin' },
left: { style: 'thin' },
right: { style: 'thin' },
},
alignment: {
wrapText: true,
},
font: {
italic: true,
size: 9,
color: { argb: '000000' },
},
fill: {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: 'CFD8DC',
},
},
});
_cellStyle.set(this, {
alignment: {
vertical: 'middle',
wrapText: true,
},
});
_directory.set(this, (key, group) => {
let hashedFolder = hash({
folder: this.folder,
userFolder: this.userFolder,
});
if (!group) {
return `dir1=${this.folder}&dir2=U-${hashedFolder}&dir3=${key || ''}`;
}
hashedFolder = hash({
folder: this.folder,
group,
});
return `dir1=${this.folder}&dir2=G-${hashedFolder}&dir3=${key || ''}`;
});
this.generateTemplate = (template) => __awaiter(this, void 0, void 0, function* () {
const { fileName, columns, sheets } = template;
if (!Array.isArray(columns)) {
throw new Error('Excel template columns must be an array');
}
for (const [idx, column] of columns.entries()) {
if (!column.field) {
throw new Error(`Column ${idx + 1}: Field is required`);
}
if (!column.title) {
throw new Error(`Column ${idx + 1}: Title is required`);
}
}
const hasDescription = columns.some(column => column.description);
const workbook = new Workbook(); //await XlsxPopulate.fromBlankAsync(); // Đọc file sau khi đã download
const firstSheet = workbook.addWorksheet('template'); // Lấy ra sheet đầu tiên
columns.forEach((column, index) => {
var _a, _b, _c, _d, _e, _f;
const { required, fill, fontColor } = column;
const cellField = firstSheet.getCell(1, index + 1);
const cellTitle = firstSheet.getCell(2, index + 1);
const cellDescription = firstSheet.getCell(3, index + 1);
let width = 120;
if (column.width && column.width.endsWith('px')) {
width = +column.width.replace('px', '');
}
firstSheet.getColumn(index + 1).width = width / 7 || 20;
cellField.style = __classPrivateFieldGet(this, _fieldStyle);
if (required) {
cellField.style = __classPrivateFieldGet(this, _requiredStyle);
}
else {
cellField.style = __classPrivateFieldGet(this, _fieldStyle);
}
cellTitle.style = Object.assign(Object.assign({}, __classPrivateFieldGet(this, _titleStyle)), { font: Object.assign(Object.assign({}, (_a = __classPrivateFieldGet(this, _titleStyle)) === null || _a === void 0 ? void 0 : _a.font), { color: Object.assign(Object.assign({}, (_c = (_b = __classPrivateFieldGet(this, _titleStyle)) === null || _b === void 0 ? void 0 : _b.font) === null || _c === void 0 ? void 0 : _c.color), { argb: fontColor || ((_f = (_e = (_d = __classPrivateFieldGet(this, _titleStyle)) === null || _d === void 0 ? void 0 : _d.font) === null || _e === void 0 ? void 0 : _e.color) === null || _f === void 0 ? void 0 : _f.argb) }) }), fill: {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: fill || __classPrivateFieldGet(this, _titleFgColor),
},
} });
cellField.value = column.field;
cellTitle.value = column.title;
if (hasDescription) {
cellDescription.style = __classPrivateFieldGet(this, _descriptionStyle);
cellDescription.value = column.description || '';
}
});
if (sheets === null || sheets === void 0 ? void 0 : sheets.length) {
for (const sheet of sheets) {
if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.fields)) {
const newSheet = workbook.addWorksheet(sheet.name);
sheet.fields.forEach((field, index) => {
newSheet.getColumn(index + 1).width = 30;
newSheet.getCell(1, index + 1).style = __classPrivateFieldGet(this, _titleStyle);
newSheet.getCell(1, index + 1).value = field;
});
sheet.items.forEach((item, idx1) => {
sheet.fields.forEach((field, idx2) => {
newSheet.getCell(2 + idx1, 1 + idx2).value = item[field];
newSheet.getCell(2 + idx1, 1 + idx2).style = __classPrivateFieldGet(this, _cellStyle);
});
});
}
}
}
const file = yield workbook.xlsx.writeBuffer();
SdUtility.downloadBlob(new Blob([file], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), fileName);
});
this.uploadTemplate = (args) => __awaiter(this, void 0, void 0, function* () {
const { key, group, validator } = args;
const { uploadTemplate } = API;
const url = `${this.functionUrl}${uploadTemplate}?${__classPrivateFieldGet(this, _directory).call(this, key, group)}`;
const file = yield SdUtility.upload({
extensions: ['xlsx'],
maxSizeInMb: 0.1,
validator,
});
if (file) {
const { filePath, fileName } = yield this.apiService.upload(url, file).catch((err) => {
this.notifyService.notify.warning(err === null || err === void 0 ? void 0 : err.message);
throw err;
});
return {
filePath,
fileName,
};
}
return null;
});
this.generateUploadTemplate = (args) => __awaiter(this, void 0, void 0, function* () {
const { key, template, group } = args;
const { generateUploadTemplate } = API;
const url = `${this.functionUrl}${generateUploadTemplate}?${__classPrivateFieldGet(this, _directory).call(this, key, group)}`;
const { filePath, fileName } = yield this.apiService.post(url, template);
return { filePath, fileName };
});
this.removeFile = (args) => __awaiter(this, void 0, void 0, function* () {
const { key, group, fileName } = args;
const { removeFile } = API;
const url = `${this.functionUrl}${removeFile}?${__classPrivateFieldGet(this, _directory).call(this, key, group)}&name=${fileName}`;
yield this.apiService.post(url);
});
this.filesInFolder = (args) => __awaiter(this, void 0, void 0, function* () {
var _a;
const { key, group } = args;
const { filesInFolder } = API;
const url = `${this.functionUrl}${filesInFolder}?${__classPrivateFieldGet(this, _directory).call(this, key, group)}`;
const res = yield this.apiService.get(url);
return (((_a = res.files) === null || _a === void 0 ? void 0 : _a.map(e => ({
filePath: e.publicUrl,
fileName: e.name,
}))) || []);
});
this.download = (filePath, fileName) => {
const link = document.createElement('a');
link.download = `${fileName || v4()}.xlsx`;
link.href = filePath;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
this.exportByTemplate = (args) => __awaiter(this, void 0, void 0, function* () {
const { filePath, columns, items, fileName } = args;
const { sdExportByTemplate } = API;
const url = `${this.functionUrl}${sdExportByTemplate}`;
const buffer = yield this.apiService.post(url, {
filePath,
columns,
items,
fileName,
}, null, {
responseType: 'arraybuffer',
});
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' });
SdUtility.downloadBlob(blob, fileName);
});
this.exportCSV = (option) => __awaiter(this, void 0, void 0, function* () {
const { columns, items, fileName } = option;
const headerCSV = {};
for (const column of columns) {
headerCSV[column.field] = column.title;
}
const csvExporter = new ExportToCsv({
filename: `${fileName || 'CSV'}_${Date.toFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss')}`,
fieldSeparator: ',',
quoteStrings: '"',
decimalSeparator: '.',
showLabels: true,
showTitle: false,
title: fileName || 'CSV',
useBom: true,
});
csvExporter.generateCsv([headerCSV, ...items]);
});
this.export = (option) => __awaiter(this, void 0, void 0, function* () {
const { columns, items, fileName, sheets } = option;
let hasDescription = false;
for (const [idx, column] of columns.entries()) {
if (!column.field) {
throw new Error(`Column ${idx + 1}: Field is required`);
}
if (!column.title) {
throw new Error(`Column ${idx + 1}: Title is required`);
}
if (column.description) {
hasDescription = true;
}
}
const workbook = new Workbook(); //await XlsxPopulate.fromBlankAsync(); // Đọc file sau khi đã download
const firstSheet = workbook.addWorksheet('data'); // Lấy ra sheet đầu tiên
columns.forEach((column, index) => {
let width = 120;
if (column.width && column.width.endsWith('px')) {
width = +column.width.replace('px', '');
}
firstSheet.getColumn(index + 1).width = width / 7 || 20;
firstSheet.getCell(1, index + 1).style = __classPrivateFieldGet(this, _fieldStyle);
if (column.required) {
firstSheet.getCell(2, index + 1).style = __classPrivateFieldGet(this, _requiredStyle);
}
else {
firstSheet.getCell(2, index + 1).style = __classPrivateFieldGet(this, _titleStyle);
}
firstSheet.getCell(1, index + 1).value = column.field;
firstSheet.getCell(2, index + 1).value = column.title;
if (hasDescription) {
firstSheet.getCell(3, index + 1).style = __classPrivateFieldGet(this, _descriptionStyle);
firstSheet.getCell(3, index + 1).value = column.description || '';
}
});
if (sheets === null || sheets === void 0 ? void 0 : sheets.length) {
for (const sheet of sheets) {
if (sheet.name && Array.isArray(sheet.items) && Array.isArray(sheet.fields)) {
const newSheet = workbook.addWorksheet(sheet.name);
sheet.fields.forEach((field, index) => {
newSheet.getColumn(index + 1).width = 30;
newSheet.getCell(1, index + 1).style = __classPrivateFieldGet(this, _titleStyle);
newSheet.getCell(1, index + 1).value = field;
});
sheet.items.forEach((item, idx1) => {
sheet.fields.forEach((field, idx2) => {
newSheet.getCell(2 + idx1, 1 + idx2).value = item[field];
newSheet.getCell(2 + idx1, 1 + idx2).style = __classPrivateFieldGet(this, _cellStyle);
});
});
}
}
}
const fromRow = hasDescription ? 4 : 3;
items.forEach((e, idx1) => {
columns.forEach((column, idx2) => {
if (typeof e[column.field] === 'number') {
// Format mặc định với kiểu số
firstSheet.getCell(fromRow + idx1, 1 + idx2).value = +e[column.field];
firstSheet.getCell(fromRow + idx1, 1 + idx2).numFmt = '#';
}
else {
firstSheet.getCell(fromRow + idx1, 1 + idx2).value = e[column.field];
}
firstSheet.getCell(fromRow + idx1, 1 + idx2).style = Object.assign({}, __classPrivateFieldGet(this, _cellStyle));
});
});
const file = yield workbook.xlsx.writeBuffer();
SdUtility.downloadBlob(new Blob([file], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), fileName);
});
this.exportCustom = (option) => __awaiter(this, void 0, void 0, function* () {
const { fileName, sheets } = option;
if (!(sheets === null || sheets === void 0 ? void 0 : sheets.length)) {
this.notifyService.notify.warning('Phải có ít nhất 1 sheet');
return;
}
const workbook = new Workbook();
for (const [idx, sheet] of sheets.entries()) {
const { name, columns, cells } = sheet;
const worksheet = workbook.addWorksheet(name || `Sheet ${idx + 1}`);
for (const column of columns || []) {
worksheet.getColumn(column.index).style = column.style;
worksheet.getColumn(column.index).width = column.width;
}
for (const cell of cells) {
const { row, column, value, style } = cell;
worksheet.getCell(row, column).style = style || worksheet.getColumn(column).style;
worksheet.getCell(row, column).value = value;
}
}
const file = yield workbook.xlsx.writeBuffer();
SdUtility.downloadBlob(new Blob([file], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), fileName);
});
this.mergePDF = (urls) => __awaiter(this, void 0, void 0, function* () {
const { sdMergePDF } = API;
const url = `${this.functionUrl}${sdMergePDF}`;
const buffer = yield this.apiService.post(url, {
urls,
}, null, {
responseType: 'arraybuffer',
});
SdUtility.downloadBlob(new Blob([buffer], { type: 'application/pdf' }));
});
this.uploadXlsx = () => __awaiter(this, void 0, void 0, function* () {
return yield SdUtility.upload({
extensions: ['xlsx'],
maxSizeInMb: 10,
}).then(file => {
return this.parseXlsx(file);
});
});
this.parseXlsx = (file) => __awaiter(this, void 0, void 0, function* () {
if (file) {
return new Promise((resolve, reject) => {
const wb = new Workbook();
const reader = new FileReader();
reader.onload = () => {
const buffer = reader.result;
if (!buffer) {
reject('Có lỗi xảy ra khi đọc file');
return;
}
wb.xlsx.load(buffer).then(workbook => {
const sheet = workbook.worksheets[0];
if (!sheet) {
reject('Không tìm thấy dữ liệu');
return;
}
const items = [];
const headers = sheet.getRow(1).values;
if (Array.isArray(headers)) {
sheet.eachRow((row, rowIndex) => {
const { hasValues, values } = row;
// console.log(row, hasValues, values)
if (hasValues && rowIndex > 1) {
const item = {};
headers.forEach((cellValue, index) => {
if (cellValue) {
const field = cellValue.toString();
item[field] = values[index];
if (typeof item[field] === 'string') {
item[field] = item[field].trim();
}
if (item[field] === '' || item[field] === undefined) {
item[field] = null;
}
}
});
items.push(item);
}
});
resolve({
items,
file,
});
}
});
};
reader.readAsArrayBuffer(file);
});
}
else {
return {
items: [],
file: null,
};
}
});
}
get functionUrl() {
var _a;
return (_a = this.firebaseConfiguration) === null || _a === void 0 ? void 0 : _a.functionUrl;
}
get folder() {
const { project, env } = this.firebaseConfiguration;
return `${project}-${env}`;
}
get userFolder() {
const { folder } = this.firebaseConfiguration;
if (!folder) {
return;
}
if (typeof folder === 'string') {
return folder;
}
return folder();
}
}
_fieldStyle = new WeakMap(), _titleColor = new WeakMap(), _titleFgColor = new WeakMap(), _titleStyle = new WeakMap(), _requiredStyle = new WeakMap(), _descriptionStyle = new WeakMap(), _cellStyle = new WeakMap(), _directory = new WeakMap();
SdExportService.ɵprov = ɵɵdefineInjectable({ factory: function SdExportService_Factory() { return new SdExportService(ɵɵinject(SdApiService), ɵɵinject(SdNotifyService), ɵɵinject(FIREBASE_CONFIG, 8)); }, token: SdExportService, providedIn: "root" });
SdExportService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root',
},] }
];
SdExportService.ctorParameters = () => [
{ type: SdApiService },
{ type: SdNotifyService },
{ type: undefined, decorators: [{ type: Inject, args: [FIREBASE_CONFIG,] }, { type: Optional }] }
];
/**
* Generated bundle index. Do not edit.
*/
export { API, SdExportService };
//# sourceMappingURL=sd-angular-core-export.js.map