From 429af4aac96a46698f931284b9a46258f3a02e60 Mon Sep 17 00:00:00 2001 From: Kenneth Bruskiewicz Date: Thu, 22 Aug 2024 13:37:38 -0700 Subject: [PATCH] re-add sections to excel exports. empty files export both sections and slot headers. --- lib/Toolbar.js | 16 ++++++++++--- lib/utils/files.js | 56 +++++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/lib/Toolbar.js b/lib/Toolbar.js index 18d65996..fc3f116f 100644 --- a/lib/Toolbar.js +++ b/lib/Toolbar.js @@ -12,7 +12,7 @@ import { createWorkbookFromJSON, exportWorkbook, importJsonFile, - prependRowWithValuesAcrossSheets + prependToSheet, } from '@/lib/utils/files'; import { nullValuesToString, isEmptyUnitVal } from '@/lib/utils/general'; import { MULTIVALUED_DELIMITER, titleOverText } from '@/lib/utils/fields'; @@ -493,7 +493,7 @@ class Toolbar { }) .join(MULTIVALUED_DELIMITER); } else { - if (!(v in merged_permissible_values)) console.warn(`${_v} not in merged_permissible_values ${Object.keys(merged_permissible_values)}`); + if (!(v in merged_permissible_values)) console.warn(`${v} not in merged_permissible_values ${Object.keys(merged_permissible_values)}`); nv = v in merged_permissible_values ? titleOverText(merged_permissible_values[v]) @@ -536,9 +536,19 @@ class Toolbar { }, {} ); + const columnCoordinatesByClass = Object.values(this.context.dhs).reduce( + (acc, dh) => { + const columnIndexCoordinates = dh.getFields().reduce((acc, field, i) => Object.assign(acc, { [field.name]: i }), {}); + return Object.assign(acc, { [rangeToContainerClass(schema_container, dh.class_assignment)]: invert(columnIndexCoordinates) }); + }, {}); let MultiEntityWorkbook = createWorkbookFromJSON(JSONFormat.Container); - MultiEntityWorkbook = prependRowWithValuesAcrossSheets(MultiEntityWorkbook, sectionCoordinatesByClass); + MultiEntityWorkbook.SheetNames.forEach(sheetName => { + if (!(JSONFormat.Container[sheetName].length > 0)) { + prependToSheet(MultiEntityWorkbook, sheetName, columnCoordinatesByClass[sheetName]); + } + prependToSheet(MultiEntityWorkbook, sheetName, sectionCoordinatesByClass[sheetName]); + }); await this.context.runBehindLoadingScreen(exportWorkbook, [ MultiEntityWorkbook, diff --git a/lib/utils/files.js b/lib/utils/files.js index 802ea392..30374d04 100644 --- a/lib/utils/files.js +++ b/lib/utils/files.js @@ -169,7 +169,7 @@ export function exportWorkbook(workbook, baseName, ext) { baseName, 'csv', ',', - 'text/plain;charset=UTF-8' + 'text/plain;charset=UTF-8', ); break; @@ -179,7 +179,7 @@ export function exportWorkbook(workbook, baseName, ext) { baseName, 'csv', ',', - 'text/plain;charset=UTF-16LE' + 'text/plain;charset=UTF-16LE', ); break; @@ -189,7 +189,7 @@ export function exportWorkbook(workbook, baseName, ext) { baseName, 'tsv', '\t', - 'text/plain;charset=UTF-8' + 'text/plain;charset=UTF-8', ); break; @@ -199,7 +199,7 @@ export function exportWorkbook(workbook, baseName, ext) { baseName, 'tsv', '\t', - 'text/plain;charset=UTF-16LE' + 'text/plain;charset=UTF-16LE', ); break; @@ -241,6 +241,8 @@ function processAndSave( const worksheet = workbook.Sheets[sheetName]; const sheetData = XlsxUtils.sheet_to_json(worksheet, { header: 1 }); + + console.log(worksheet, sheetData); const formattedData = sheetData .map((row) => row.join(delimiter)) @@ -331,42 +333,44 @@ export function importJsonFile(jsonData) { // Main function to handle the entire process of prepending row to sheets // Useful for custom binning headers like sections // NOTE: in-place function! -function prependRowForSheet(workbook, sheetName, valueCellPairs) { - // Function to read a worksheet and convert it to a 2D array +export const modifySheetRow = (workbook, sheetName, valueCellPairs, targetRow) => { + + // Utility function to read a worksheet and convert it to a 2D array const getSheetData = (workbook, sheetName) => { const worksheet = workbook.Sheets[sheetName]; return XlsxUtils.sheet_to_json(worksheet, { header: 1 }); - } + }; - // Function to prepend an empty row to the data array - const prependEmptyRow = (data) => { - data.unshift([]); - } + // Utility function to update the worksheet in the workbook + const updateWorksheet = (workbook, sheetName, data) => { + const newWorksheet = XlsxUtils.aoa_to_sheet(data); + workbook.Sheets[sheetName] = newWorksheet; + }; + + // Function to populate or prepend a row in a worksheet + const populateOrPrependRow = (data, valueCellPairs, targetRow) => { + if (targetRow === undefined || targetRow < 0 || targetRow >= data.length) { + data.unshift([]); + targetRow = 0; + } - // Function to insert values into the top row based on cell-value pairs - function populateTopRow(data, valueCellPairs) { for (const [colIndex, value] of Object.entries(valueCellPairs)) { - data[0][Number(colIndex)] = value; // Assume zero-based index + data[targetRow][Number(colIndex)] = value; } -} + }; - // Function to convert the 2D array back to a worksheet and update the workbook - const updateWorksheet = (workbook, sheetName, data) => { - const newWorksheet = XlsxUtils.aoa_to_sheet(data); - workbook.Sheets[sheetName] = newWorksheet; - } + const data = getSheetData(workbook, sheetName); + populateOrPrependRow(data, valueCellPairs, targetRow); + updateWorksheet(workbook, sheetName, data); +}; - let data = getSheetData(workbook, sheetName); // Get the data array - prependEmptyRow(data); // Prepend an empty row - populateTopRow(data, valueCellPairs); // Populate the top row with values - updateWorksheet(workbook, sheetName, data); // Update the worksheet in the workbook -} +export const prependToSheet = (workbook, sheetName, valueCellPairs) => modifySheetRow(workbook, sheetName, valueCellPairs); // Main function to handle the entire process across all sheets export function prependRowWithValuesAcrossSheets(workbook, valueCellPairs) { const newWorkbook = structuredClone(workbook); newWorkbook.SheetNames.forEach(sheetName => { - prependRowForSheet(newWorkbook, sheetName, valueCellPairs[sheetName]); + prependToSheet(newWorkbook, sheetName, valueCellPairs[sheetName]); }); return newWorkbook; } \ No newline at end of file