REFACTOR: Trocado a biblioteca para tratamento de xlsx
This commit is contained in:
parent
a3245592c8
commit
4c7d5e33d0
805
package-lock.json
generated
805
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"csv-parser": "^3.0.0",
|
"csv-parser": "^3.0.0",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-session": "^1.18.2",
|
"express-session": "^1.18.2",
|
||||||
"fast-csv": "^4.3.6",
|
"fast-csv": "^4.3.6",
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const { consultarViabilidade, discoverDataType } = require('./viabilidadeService
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const XLSX = require('xlsx');
|
const XLSX = require('xlsx');
|
||||||
|
const ExcelJS = require('exceljs');
|
||||||
const { once } = require('events');
|
const { once } = require('events');
|
||||||
const {
|
const {
|
||||||
incrementProcessed,
|
incrementProcessed,
|
||||||
@ -45,6 +46,14 @@ function isExcelFile(filePath) {
|
|||||||
return isZipBasedXlsx || isOleBasedXls || isHtmlExcel;
|
return isZipBasedXlsx || isOleBasedXls || isHtmlExcel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isXlsxFile(filePath) {
|
||||||
|
const ext = path.extname(filePath).toLowerCase();
|
||||||
|
if (ext === '.xlsx') return true;
|
||||||
|
|
||||||
|
const fileStart = fs.readFileSync(filePath).subarray(0, 4);
|
||||||
|
return fileStart[0] === 0x50 && fileStart[1] === 0x4b;
|
||||||
|
}
|
||||||
|
|
||||||
function detectDelimiter(line) {
|
function detectDelimiter(line) {
|
||||||
const delimiters = [';', '\t', ','];
|
const delimiters = [';', '\t', ','];
|
||||||
return delimiters
|
return delimiters
|
||||||
@ -247,6 +256,70 @@ function buildErrorResultColumns(err) {
|
|||||||
return ['', '', '', '', cleanCsvValue(formatApiErrorResponse(err))];
|
return ['', '', '', '', cleanCsvValue(formatApiErrorResponse(err))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cloneCellStyle(cell) {
|
||||||
|
return {
|
||||||
|
numFmt: cell.numFmt,
|
||||||
|
font: cell.font ? { ...cell.font } : undefined,
|
||||||
|
alignment: cell.alignment ? { ...cell.alignment } : undefined,
|
||||||
|
border: cell.border ? { ...cell.border } : undefined,
|
||||||
|
fill: cell.fill ? { ...cell.fill } : undefined,
|
||||||
|
protection: cell.protection ? { ...cell.protection } : undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function styleInsertedResultColumns(worksheet, headerRowNumber) {
|
||||||
|
RESULT_HEADERS.forEach((header, index) => {
|
||||||
|
const columnNumber = index + 1;
|
||||||
|
const sourceColumn = worksheet.getColumn(RESULT_HEADERS.length + 1);
|
||||||
|
const targetColumn = worksheet.getColumn(columnNumber);
|
||||||
|
targetColumn.width = Math.max(16, sourceColumn.width || 0);
|
||||||
|
|
||||||
|
const headerCell = worksheet.getRow(headerRowNumber).getCell(columnNumber);
|
||||||
|
const sourceHeaderCell = worksheet.getRow(headerRowNumber).getCell(RESULT_HEADERS.length + 1);
|
||||||
|
headerCell.value = header;
|
||||||
|
headerCell.style = cloneCellStyle(sourceHeaderCell);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processXlsxFile(jobId, inputPath, outputPath, rows, headerRowIndex, indexes) {
|
||||||
|
const workbook = new ExcelJS.Workbook();
|
||||||
|
await workbook.xlsx.readFile(inputPath);
|
||||||
|
|
||||||
|
const worksheet = workbook.worksheets[0];
|
||||||
|
const headerRowNumber = headerRowIndex + 1;
|
||||||
|
worksheet.spliceColumns(1, 0, ...RESULT_HEADERS.map(() => []));
|
||||||
|
styleInsertedResultColumns(worksheet, headerRowNumber);
|
||||||
|
|
||||||
|
for (let rowIndex = headerRowIndex + 1; rowIndex < rows.length; rowIndex++) {
|
||||||
|
const cols = rows[rowIndex];
|
||||||
|
const geoPayload = buildGeoPayload(cols, indexes);
|
||||||
|
const cepPayload = buildCepPayload(cols, indexes);
|
||||||
|
if (!geoPayload && !cepPayload) continue;
|
||||||
|
|
||||||
|
const row = worksheet.getRow(rowIndex + 1);
|
||||||
|
try {
|
||||||
|
const viab = await consultarComFallback(geoPayload, cepPayload);
|
||||||
|
buildSuccessResultColumns(viab).forEach((value, index) => {
|
||||||
|
const cell = row.getCell(index + 1);
|
||||||
|
cell.value = value;
|
||||||
|
cell.style = cloneCellStyle(row.getCell(RESULT_HEADERS.length + 1));
|
||||||
|
});
|
||||||
|
incrementProcessed(jobId);
|
||||||
|
} catch (err) {
|
||||||
|
buildErrorResultColumns(err).forEach((value, index) => {
|
||||||
|
const cell = row.getCell(index + 1);
|
||||||
|
cell.value = value;
|
||||||
|
cell.style = cloneCellStyle(row.getCell(RESULT_HEADERS.length + 1));
|
||||||
|
});
|
||||||
|
incrementErrors(jobId);
|
||||||
|
incrementProcessed(jobId);
|
||||||
|
}
|
||||||
|
row.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
await workbook.xlsx.writeFile(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
function shiftCellAddress(address, colOffset) {
|
function shiftCellAddress(address, colOffset) {
|
||||||
const decoded = XLSX.utils.decode_cell(address);
|
const decoded = XLSX.utils.decode_cell(address);
|
||||||
decoded.c += colOffset;
|
decoded.c += colOffset;
|
||||||
@ -338,6 +411,13 @@ async function processCsvFile(jobId, inputPath, originalName) {
|
|||||||
const outputPath = path.join(__dirname, '..', 'outputs', outputFilename);
|
const outputPath = path.join(__dirname, '..', 'outputs', outputFilename);
|
||||||
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
||||||
|
|
||||||
|
if (isXlsxFile(inputPath)) {
|
||||||
|
await processXlsxFile(jobId, inputPath, outputPath, rows, headerRowIndex, indexes);
|
||||||
|
finishJob(jobId, path.basename(outputPath));
|
||||||
|
|
||||||
|
return outputPath;
|
||||||
|
}
|
||||||
|
|
||||||
if (isExcel) {
|
if (isExcel) {
|
||||||
const workbook = XLSX.readFile(inputPath, { cellDates: false, raw: false, cellStyles: true });
|
const workbook = XLSX.readFile(inputPath, { cellDates: false, raw: false, cellStyles: true });
|
||||||
const firstSheetName = workbook.SheetNames[0];
|
const firstSheetName = workbook.SheetNames[0];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user