Skip to content

Commit eb1a637

Browse files
Or-MiOr-Mi
authored andcommitted
fixing write workbook
1 parent c737fa1 commit eb1a637

File tree

1 file changed

+172
-49
lines changed

1 file changed

+172
-49
lines changed

src/taskpane/components/App.tsx

Lines changed: 172 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
ProgressBar,
1717
shorthands
1818
} from "@fluentui/react-components";
19-
import { getCellAddress } from "../taskpane";
2019
import { useState } from "react";
2120
import pako from 'pako';
2221

@@ -135,6 +134,15 @@ const useStyles = makeStyles({
135134
}
136135
});
137136

137+
// Helper to convert Excel column letters to zero-based index
138+
function columnLetterToIndex(colLetters: string) {
139+
let col = 0;
140+
for (let i = 0; i < colLetters.length; i++) {
141+
col = col * 26 + (colLetters.charCodeAt(i) - 64); // 'A' is 65 in ASCII
142+
}
143+
return col - 1; // zero-based
144+
}
145+
138146
const App = () => {
139147
const styles = useStyles();
140148
const [selectedTab, setSelectedTab] = useState("read");
@@ -205,11 +213,20 @@ const App = () => {
205213

206214
for (let row = 0; row < range.rowCount; row++) {
207215
for (let col = 0; col < range.columnCount; col++) {
216+
const address = properties.value[row][col].address;
217+
const match = address.match(/!([A-Z]+)(\d+)$/);
218+
let rowIndex = 0, columnIndex = 0; // fallback if parsing fails
219+
if (match) {
220+
const colLetters = match[1];
221+
const rowNumber = parseInt(match[2], 10);
222+
rowIndex = rowNumber - 1; // zero-based
223+
columnIndex = columnLetterToIndex(colLetters);
224+
}
208225
const cellData = {
209226
formulaR1C1: range.formulasR1C1[row][col],
210-
address: properties.value[row][col].address,
211-
rowIndex: row,
212-
columnIndex: col,
227+
address: address,
228+
rowIndex: rowIndex,
229+
columnIndex: columnIndex,
213230
format: {
214231
font: {
215232
bold: properties.value[row][col].format.font.bold,
@@ -358,11 +375,150 @@ const App = () => {
358375
}
359376
};
360377

378+
// const convertTo2DArray = async function (cellDict) {
379+
// // Helper function to parse row and column from address (e.g., "Summary!A3" -> row 3, col A)
380+
// function parseAddress(address) {
381+
// const match = address.match(/!([A-Z]+)(\d+)/);
382+
// if (!match) return { row: 0, col: 0 };
383+
// const colLetter = match[1];
384+
// const row = parseInt(match[2], 10) - 1; // Convert to 0-based index
385+
// // Convert column letter to 0-based index (A=0, B=1, etc.)
386+
// let col = 0;
387+
// for (let i = 0; i < colLetter.length; i++) {
388+
// col = col * 26 + (colLetter.charCodeAt(i) - 65 + 1);
389+
// }
390+
// return { row, col: col - 1 }; // Adjust to 0-based
391+
// }
392+
393+
// // Find maximum row and column indices
394+
// let maxRow = 0;
395+
// let maxCol = 0;
396+
// for (const cell of Object.values(cellDict)) {
397+
// const { row, col } = parseAddress(cell.address);
398+
// maxRow = Math.max(maxRow, row);
399+
// maxCol = Math.max(maxCol, col);
400+
// }
401+
402+
// // Initialize three 2D arrays
403+
// const properties = Array(maxRow + 1).fill().map(() => Array(maxCol + 1).fill(undefined));
404+
// const formulas = Array(maxRow + 1).fill().map(() => Array(maxCol + 1).fill(undefined));
405+
// const numberFormats = Array(maxRow + 1).fill().map(() => Array(maxCol + 1).fill(undefined));
406+
407+
// // Populate the arrays
408+
// for (const cell of Object.values(cellDict)) {
409+
// const { row, col } = parseAddress(cell.address);
410+
// // Properties array
411+
// properties[row][col] = {
412+
// format: {
413+
// fill: {
414+
// color: cell.format.backgroundColor
415+
// },
416+
// font: {
417+
// bold: cell.format.font.bold,
418+
// color: cell.format.font.color,
419+
// italic: cell.format.font.italic,
420+
// name: cell.format.font.name,
421+
// size: cell.format.font.size,
422+
// strikethrough: cell.format.font.strikethrough || false, // Default to false if undefined
423+
// underline: cell.format.font.underline
424+
// }
425+
// }
426+
// };
427+
// // Formulas array
428+
// formulas[row][col] = cell.formulaR1C1;
429+
// // Number formats array
430+
// numberFormats[row][col] = cell.format.numberFormat;
431+
// }
432+
433+
// return { properties, formulas, numberFormats };
434+
// }
435+
436+
function parseExcelJsonTo2DArrays(jsonData) {
437+
// Find the maximum row and column indices
438+
let maxRow = 0;
439+
let maxCol = 0;
440+
441+
Object.values(jsonData).forEach((cell: any) => {
442+
maxRow = Math.max(maxRow, cell.rowIndex);
443+
maxCol = Math.max(maxCol, cell.columnIndex);
444+
});
445+
446+
// Initialize 2D arrays with appropriate dimensions
447+
const properties: Excel.SettableCellProperties [][] = [];
448+
const formulas = [];
449+
const numberFormats = [];
450+
451+
// Initialize arrays with empty values
452+
for (let row = 0; row <= maxRow; row++) {
453+
properties[row] = [];
454+
formulas[row] = [];
455+
numberFormats[row] = [];
456+
457+
for (let col = 0; col <= maxCol; col++) {
458+
// Default values for empty cells - RangeUpdateData format
459+
properties[row][col] = {
460+
format: {
461+
fill: {
462+
color: "#FFFFFF"
463+
},
464+
font: {
465+
bold: false,
466+
color: "#000000",
467+
italic: false,
468+
name: "Calibri",
469+
size: 11,
470+
strikethrough: false,
471+
underline: Excel.RangeUnderlineStyle.none
472+
}
473+
}
474+
};
475+
formulas[row][col] = "";
476+
numberFormats[row][col] = "General";
477+
}
478+
}
479+
480+
// Populate arrays with actual data
481+
Object.values(jsonData).forEach((cell: any) => {
482+
const { rowIndex, columnIndex } = cell;
483+
484+
// Properties array - RangeUpdateData format
485+
properties[rowIndex][columnIndex] = {
486+
format: {
487+
fill: {
488+
color: cell.format.backgroundColor
489+
},
490+
font: {
491+
bold: cell.format.font.bold,
492+
color: cell.format.font.color,
493+
italic: cell.format.font.italic,
494+
name: cell.format.font.name,
495+
size: cell.format.font.size,
496+
strikethrough: cell.format.font.strikethrough || false,
497+
underline: cell.format.font.underline.toLowerCase() === "none"
498+
? Excel.RangeUnderlineStyle.none
499+
: Excel.RangeUnderlineStyle.single
500+
}
501+
}
502+
};
503+
504+
// Formulas array
505+
formulas[rowIndex][columnIndex] = cell.formulaR1C1;
506+
507+
// Number formats array
508+
numberFormats[rowIndex][columnIndex] = cell.format.numberFormat;
509+
});
510+
511+
return {
512+
properties,
513+
formulas,
514+
numberFormats
515+
};
516+
}
517+
361518
const writeWorkbook = async (jsonData: any) => {
362519
await Excel.run(async (context) => {
363520
try {
364-
const workbook = context.workbook;
365-
const worksheets = workbook.worksheets;
521+
const worksheets = context.workbook.worksheets;
366522

367523
// Loop through each worksheet in the JSON data
368524
for (const sheetData of jsonData.worksheets) {
@@ -372,53 +528,20 @@ const App = () => {
372528
// If the worksheet does not exist, create it
373529
if (worksheet.isNullObject) {
374530
worksheet = worksheets.add(sheetData.name);
531+
worksheet.activate();
375532
}
376533

377-
// Loop through each cell in the worksheet
378-
for (const cellAddress in sheetData.cells) {
379-
const cellData = sheetData.cells[cellAddress];
380-
const range = worksheet.getRange(cellAddress);
381-
382-
// Set cell value
383-
if (cellData.value !== undefined) {
384-
range.values = [[cellData.value]];
385-
}
386-
387-
// Set cell formula
388-
if (cellData.formula !== undefined) {
389-
range.formulas = [[cellData.formula]];
390-
}
391-
392-
// Set cell formulaR1C1
393-
if (cellData.formulaR1C1 !== undefined) {
394-
range.formulasR1C1 = [[cellData.formulaR1C1]];
395-
}
396-
397-
// Set cell format
398-
if (cellData.format) {
399-
const format = cellData.format;
400-
401-
if (format.font) {
402-
range.format.font.name = format.font.name;
403-
range.format.font.size = format.font.size;
404-
range.format.font.bold = format.font.bold;
405-
range.format.font.italic = format.font.italic;
406-
range.format.font.underline = format.font.underline;
407-
range.format.font.strikethrough = format.font.strikethrough;
408-
range.format.font.color = format.font.color;
409-
}
410-
411-
if (format.backgroundColor) {
412-
range.format.fill.color = format.backgroundColor;
413-
}
534+
let sheet_cells = worksheet.getRange(sheetData.cells[Object.keys(sheetData.cells)[0]].address + ":" + sheetData.cells[Object.keys(sheetData.cells)[Object.keys(sheetData.cells).length -1]].address);
535+
const { properties, formulas, numberFormats } = parseExcelJsonTo2DArrays(sheetData.cells);
536+
sheet_cells.set({
537+
formulasR1C1: formulas,
538+
numberFormat: numberFormats
539+
});
540+
sheet_cells.setCellProperties(properties);
541+
sheet_cells.untrack();
414542

415-
if (format.numberFormat) {
416-
range.numberFormat = [[format.numberFormat]];
417-
}
418-
}
419-
}
543+
await context.sync();
420544
}
421-
await context.sync();
422545
} catch (error) {
423546
setWriteErrorMessage(error.message);
424547
throw error;

0 commit comments

Comments
 (0)