-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextract_cells.js
More file actions
124 lines (99 loc) · 4.05 KB
/
extract_cells.js
File metadata and controls
124 lines (99 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const fs = require('fs');
const path = require('path');
// Function to convert column letter to index (A=0, B=1, C=2, etc.)
function columnLetterToIndex(letter) {
return letter.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0);
}
// Function to parse cell reference (e.g., "C1" -> {column: 2, row: 0})
function parseCellReference(cellRef) {
const match = cellRef.match(/^([A-Z]+)(\d+)$/i);
if (!match) {
throw new Error(`Invalid cell reference: ${cellRef}`);
}
const columnLetter = match[1].toUpperCase();
const rowNumber = parseInt(match[2]);
// Convert to 0-based indices
const columnIndex = columnLetterToIndex(columnLetter);
const rowIndex = rowNumber - 1; // Convert 1-based to 0-based
return { column: columnIndex, row: rowIndex, original: cellRef };
}
// Function to get cell value from spreadsheet data
function getCellValue(sheetData, columnIndex, rowIndex) {
if (!sheetData.rows || rowIndex >= sheetData.rows.length || rowIndex < 0) {
return { exists: false, reason: 'Row out of bounds' };
}
const row = sheetData.rows[rowIndex];
if (!row || columnIndex >= row.length || columnIndex < 0) {
return { exists: false, reason: 'Column out of bounds' };
}
const cellValue = row[columnIndex];
return {
exists: true,
value: cellValue,
type: typeof cellValue === 'object' ? 'formula' : typeof cellValue,
isEmpty: cellValue === null || cellValue === undefined || cellValue === ''
};
}
// Function to format cell details for output
function formatCellDetails(cellRef, cellInfo, sheetName) {
const { original } = cellRef;
if (!cellInfo.exists) {
return `${original}: [ERROR] ${cellInfo.reason}`;
}
if (cellInfo.isEmpty) {
return `${original}: <empty>`;
}
if (cellInfo.type === 'formula' && cellInfo.value.formula) {
return `${original}: ${cellInfo.value.formula} (evaluates to: ${cellInfo.value.value})`;
}
return `${original}: ${cellInfo.value}`;
}
// Main function
function extractCells() {
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node extract_cells.js <spreadsheet.json> <cell1> [cell2] [cell3] ...');
console.error('Example: node extract_cells.js spreadsheet.json C1 C20 E40');
process.exit(1);
}
const jsonFilePath = args[0];
const cellReferences = args.slice(1);
// Check if file exists
if (!fs.existsSync(jsonFilePath)) {
console.error(`❌ File not found: ${jsonFilePath}`);
process.exit(1);
}
try {
// Read and parse JSON file
const jsonData = JSON.parse(fs.readFileSync(jsonFilePath, 'utf-8'));
// Get the first sheet (or we could make this configurable)
const sheetNames = Object.keys(jsonData);
if (sheetNames.length === 0) {
console.error('❌ No sheets found in the spreadsheet data');
process.exit(1);
}
const sheetName = sheetNames[0]; // Use first sheet by default
const sheetData = jsonData[sheetName];
if (sheetNames.length > 1) {
console.log(`📋 Using sheet: "${sheetName}" (${sheetNames.length} sheets available)`);
console.log('');
}
// Process each cell reference
cellReferences.forEach(cellRefString => {
try {
const cellRef = parseCellReference(cellRefString);
const cellInfo = getCellValue(sheetData, cellRef.column, cellRef.row);
const output = formatCellDetails(cellRef, cellInfo, sheetName);
console.log(output);
} catch (error) {
console.log(`${cellRefString}: [ERROR] ${error.message}`);
}
});
} catch (error) {
console.error(`❌ Error reading JSON file: ${error.message}`);
process.exit(1);
}
}
// Run the script
extractCells();
module.exports = { parseCellReference, getCellValue, formatCellDetails };