n8n-nodes-excel-api 1.0.2 → 1.0.3
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/README.md +21 -0
- package/dist/nodes/ExcelApi/ExcelApi.node.js +74 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -589,6 +589,27 @@ range: "A1:D100"
|
|
|
589
589
|
|
|
590
590
|
## 🆕 Latest Features
|
|
591
591
|
|
|
592
|
+
### 🎉 Automatic Type Conversion (v1.0.3)
|
|
593
|
+
- ✅ **Smart Type Detection**: Automatically convert strings to appropriate data types
|
|
594
|
+
- ✅ **Number Conversion**: `"123"` → `123`, `"45.67"` → `45.67`
|
|
595
|
+
- ✅ **Boolean Conversion**: `"true"` → `true`, `"false"` → `false`
|
|
596
|
+
- ✅ **Null Conversion**: `"null"` or empty string → `null`
|
|
597
|
+
- ✅ **Date Conversion**: ISO format date strings auto-convert (`"2024-01-15"`)
|
|
598
|
+
- ✅ **Preserve Typed Values**: Numbers, booleans, etc. remain unchanged
|
|
599
|
+
- ✅ **All Operations**: Supported in both Append and Update operations
|
|
600
|
+
|
|
601
|
+
**Example:**
|
|
602
|
+
```json
|
|
603
|
+
{
|
|
604
|
+
"EmployeeID": "E001", // Remains string
|
|
605
|
+
"Age": "30", // Auto-converts to number 30
|
|
606
|
+
"Salary": "50000.50", // Auto-converts to 50000.50
|
|
607
|
+
"IsActive": "true", // Auto-converts to boolean true
|
|
608
|
+
"TerminationDate": "null", // Auto-converts to null
|
|
609
|
+
"HireDate": "2020-01-15" // Auto-converts to date format
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
592
613
|
### Object Mode
|
|
593
614
|
- ✅ Uses `/api/excel/append_object` API
|
|
594
615
|
- ✅ Automatically reads Excel headers (first row)
|
|
@@ -2,6 +2,73 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ExcelApi = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
/**
|
|
6
|
+
* 自動轉換欄位值的型態
|
|
7
|
+
* 支援:數字、布林值、日期、null
|
|
8
|
+
*/
|
|
9
|
+
function convertValueType(value) {
|
|
10
|
+
// 如果已經是 null、undefined,直接返回
|
|
11
|
+
if (value === null || value === undefined) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
// 如果不是字串,保持原樣
|
|
15
|
+
if (typeof value !== 'string') {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
// 處理空字串
|
|
19
|
+
if (value.trim() === '') {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// 處理 "null" 字串
|
|
23
|
+
if (value.toLowerCase() === 'null') {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// 處理布林值
|
|
27
|
+
if (value.toLowerCase() === 'true') {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (value.toLowerCase() === 'false') {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// 處理數字(整數和浮點數)
|
|
34
|
+
// 使用正則表達式確保是有效的數字格式
|
|
35
|
+
if (/^-?\d+(\.\d+)?$/.test(value.trim())) {
|
|
36
|
+
const num = Number(value);
|
|
37
|
+
if (!isNaN(num)) {
|
|
38
|
+
return num;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// 處理 ISO 日期格式
|
|
42
|
+
// 格式如:2024-01-15 或 2024-01-15T10:30:00 或 2024-01-15T10:30:00.000Z
|
|
43
|
+
if (/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3}Z?)?)?$/.test(value.trim())) {
|
|
44
|
+
const date = new Date(value);
|
|
45
|
+
if (!isNaN(date.getTime())) {
|
|
46
|
+
// 返回 ISO 字串格式,Excel API Server 會處理
|
|
47
|
+
return date.toISOString();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 其他情況保持原字串
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 遞迴轉換物件或陣列中的所有值
|
|
55
|
+
*/
|
|
56
|
+
function convertObjectValues(obj) {
|
|
57
|
+
if (obj === null || obj === undefined) {
|
|
58
|
+
return obj;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(obj)) {
|
|
61
|
+
return obj.map(item => convertValueType(item));
|
|
62
|
+
}
|
|
63
|
+
if (typeof obj === 'object') {
|
|
64
|
+
const converted = {};
|
|
65
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
66
|
+
converted[key] = convertValueType(value);
|
|
67
|
+
}
|
|
68
|
+
return converted;
|
|
69
|
+
}
|
|
70
|
+
return convertValueType(obj);
|
|
71
|
+
}
|
|
5
72
|
class ExcelApi {
|
|
6
73
|
constructor() {
|
|
7
74
|
this.description = {
|
|
@@ -374,6 +441,8 @@ class ExcelApi {
|
|
|
374
441
|
else {
|
|
375
442
|
appendValues = appendValuesRaw;
|
|
376
443
|
}
|
|
444
|
+
// 自動轉換值的型態
|
|
445
|
+
const convertedValues = convertObjectValues(appendValues);
|
|
377
446
|
// Use different API endpoint based on append mode
|
|
378
447
|
if (appendMode === 'object') {
|
|
379
448
|
// Object Mode: Use append_object API
|
|
@@ -387,7 +456,7 @@ class ExcelApi {
|
|
|
387
456
|
body: {
|
|
388
457
|
file: fileName,
|
|
389
458
|
sheet: sheetName,
|
|
390
|
-
values:
|
|
459
|
+
values: convertedValues,
|
|
391
460
|
},
|
|
392
461
|
json: true,
|
|
393
462
|
});
|
|
@@ -404,7 +473,7 @@ class ExcelApi {
|
|
|
404
473
|
body: {
|
|
405
474
|
file: fileName,
|
|
406
475
|
sheet: sheetName,
|
|
407
|
-
values:
|
|
476
|
+
values: convertedValues,
|
|
408
477
|
},
|
|
409
478
|
json: true,
|
|
410
479
|
});
|
|
@@ -463,11 +532,13 @@ class ExcelApi {
|
|
|
463
532
|
else {
|
|
464
533
|
valuesToSet = valuesToSetRaw;
|
|
465
534
|
}
|
|
535
|
+
// 自動轉換值的型態
|
|
536
|
+
const convertedValuesToSet = convertObjectValues(valuesToSet);
|
|
466
537
|
// Build request body
|
|
467
538
|
const requestBody = {
|
|
468
539
|
file: fileName,
|
|
469
540
|
sheet: sheetName,
|
|
470
|
-
values_to_set:
|
|
541
|
+
values_to_set: convertedValuesToSet,
|
|
471
542
|
};
|
|
472
543
|
if (identifyBy === 'rowNumber') {
|
|
473
544
|
const rowNumber = this.getNodeParameter('rowNumber', i);
|