@mixd-id/web-scaffold 0.1.240411103 → 0.1.240411105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.240411103",
4
+ "version": "0.1.240411105",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -5,8 +5,8 @@ const glob = require("glob");
5
5
  const Exceljs = require("exceljs")
6
6
  const { saveBuffer, unflatten } = require('./helpers.js')
7
7
 
8
- const getCellText = (cell) => {
9
- if(!cell) return ''
8
+ const getCellText = (cell, image) => {
9
+ if(!cell) return image?.buffer ?? ''
10
10
 
11
11
  let value = ''
12
12
  if(cell.formulaType === 1){
@@ -22,10 +22,44 @@ const getCellText = (cell) => {
22
22
  value = cell.value
23
23
  }
24
24
 
25
+ // Image anchored on the cell, return its raw buffer unless the cell holds a value
26
+ if(image?.buffer && (value === null || value === undefined || value === ''))
27
+ value = image.buffer
28
+
25
29
  return value
26
30
 
27
31
  }
28
32
 
33
+ const cellKey = (row, col) => row + ',' + col
34
+
35
+ // Header labels often carry stray padding in the source file ("TEKS PROGRAM "),
36
+ // normalise them so the column mapping does not depend on it
37
+ const columnName = (value) => `${value ?? ''}`.trim()
38
+
39
+ // Maps the cell an image is anchored on to its media entry ({ buffer, extension, name }).
40
+ // Only the top left anchor counts, an image spilling over its neighbours stays on one cell.
41
+ const getWorksheetImages = (workbook, worksheet) => {
42
+
43
+ const images = new Map()
44
+
45
+ for(const item of worksheet.getImages() ?? []){
46
+
47
+ const tl = item.range?.tl
48
+ if(!tl) continue
49
+
50
+ const media = workbook.getImage(parseInt(item.imageId))
51
+ if(!media?.buffer) continue
52
+
53
+ // Anchors are 0 based, cell addresses are 1 based
54
+ const key = cellKey(tl.nativeRow + 1, tl.nativeCol + 1)
55
+
56
+ if(!images.has(key))
57
+ images.set(key, media)
58
+ }
59
+
60
+ return images
61
+ }
62
+
29
63
  const analyseRequest = async(req) => {
30
64
 
31
65
  const file = req.files[0]
@@ -88,10 +122,10 @@ const analyseRequest = async(req) => {
88
122
  header.eachCell((cell) => {
89
123
  if(cell.isMerged){
90
124
  const sub = worksheet.getCell(cell.address.replace(/\d/g, '') + '2').value
91
- columns.push(cell.value + '>' + sub)
125
+ columns.push(columnName(cell.value) + '>' + columnName(sub))
92
126
  }
93
127
  else{
94
- columns.push(cell.value)
128
+ columns.push(columnName(cell.value))
95
129
  }
96
130
  })
97
131
 
@@ -143,6 +177,8 @@ const importRequest = async(req) => {
143
177
  for(const worksheet of workbook.worksheets){
144
178
  const doc = docs.find(_ => _.name === worksheet.name)
145
179
 
180
+ const cellImages = getWorksheetImages(workbook, worksheet)
181
+
146
182
  let rows = []
147
183
  const row = worksheet.getRow(2)
148
184
  let isInfoRow = false
@@ -158,11 +194,11 @@ const importRequest = async(req) => {
158
194
  header.eachCell((cell, index) => {
159
195
  if(cell.isMerged){
160
196
  const sub = worksheet.getCell(cell.address.replace(/\d/g, '') + '2').value
161
- columnAddress[cell.value + '>' + sub] = index
197
+ columnAddress[columnName(cell.value) + '>' + columnName(sub)] = index
162
198
  rowStart = 3
163
199
  }
164
200
  else{
165
- columnAddress[cell.value] = index
201
+ columnAddress[columnName(cell.value)] = index
166
202
  }
167
203
  })
168
204
 
@@ -174,44 +210,57 @@ const importRequest = async(req) => {
174
210
  }))
175
211
  }
176
212
 
213
+ // Rows holding nothing but an image are not visited by eachRow, collect them too
214
+ const rowNumbers = new Set()
177
215
  worksheet.eachRow((row, index) => {
178
- if(index >= rowStart){
179
- const obj = {}
180
-
181
- // Check if cells in row 2 and 3 is notes in italic
182
- if(index <= 3){
183
- let isItalic = false
184
- for(let idx in keys){
185
- const key = keys[idx]
186
- if(key.value && columnAddress[key.value]){
187
- const cell = row.getCell(columnAddress[key.value])
188
- if(cell.font && cell.font.italic){
189
- isItalic = true
190
- break
191
- }
216
+ if(index >= rowStart)
217
+ rowNumbers.add(index)
218
+ })
219
+ for(const key of cellImages.keys()){
220
+ const index = parseInt(key.split(',')[0])
221
+ if(index >= rowStart)
222
+ rowNumbers.add(index)
223
+ }
224
+
225
+ for(const index of [...rowNumbers].sort((a, b) => a - b)){
226
+ const row = worksheet.getRow(index)
227
+ const obj = {}
228
+
229
+ // Check if cells in row 2 and 3 is notes in italic
230
+ if(index <= 3){
231
+ let isItalic = false
232
+ for(let idx in keys){
233
+ const key = keys[idx]
234
+ const address = columnAddress[columnName(key.value)]
235
+ if(key.value && address){
236
+ const cell = row.getCell(address)
237
+ if(cell.font && cell.font.italic){
238
+ isItalic = true
239
+ break
192
240
  }
193
241
  }
194
-
195
- if(isItalic)
196
- return
197
242
  }
198
243
 
199
- if(keys){
200
- for(let idx in keys){
201
- const key = keys[idx]
202
- if(key.value && columnAddress[key.value]){
203
- const cell = row.getCell(columnAddress[key.value])
204
- obj[key.key] = getCellText(cell)
205
- }
244
+ if(isItalic)
245
+ continue
246
+ }
247
+
248
+ if(keys){
249
+ for(let idx in keys){
250
+ const key = keys[idx]
251
+ const address = columnAddress[columnName(key.value)]
252
+ if(key.value && address){
253
+ const cell = row.getCell(address)
254
+ obj[key.key] = getCellText(cell, cellImages.get(cellKey(index, address)))
206
255
  }
207
256
  }
208
- else{
209
- //Object.assign(obj, row)
210
- }
211
-
212
- rows.push(unflatten(obj))
213
257
  }
214
- })
258
+ else{
259
+ //Object.assign(obj, row)
260
+ }
261
+
262
+ rows.push(unflatten(obj))
263
+ }
215
264
 
216
265
  Object.assign(doc, {
217
266
  rows