先核來源與已訂規則
本例只產生 Open XML 工作表儲存格片段。來源 kind 是文字,值 =1+1 就須照作文字;看到等號便改 f 公式已變原意。數字來源另按數字表示。
| 紀錄 | 輸入 JSON |
|---|---|
| 原例輸入 | {"kind":"text","value":"=1+1"} |
比較兩條實際路徑
更正用 inlineStr 及已轉義文字。這是片段類型示範,未建立 XLSX 檔案包或執行試算表,也沒有聲稱通用 CSV 引號法。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"fragment":"<c><f>1+1</f></c>"} |
| 更正路徑 | {"fragment":"<c t=\"inlineStr\"><is><t>=1+1</t></is></c>"} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const escape=s=>s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
if(i.kind==='number')return {fragment:'<c><v>'+i.value+'</v></c>'};
if(!corrected&&i.value.startsWith('='))return {fragment:'<c><f>'+escape(i.value.slice(1))+'</f></c>'};
return {fragment:'<c t="inlineStr"><is><t>'+escape(i.value)+'</t></is></c>'};
};
const cases=[{"label":"misleading base","input":{"kind":"text","value":"=1+1"},"expected":{"fragment":"<c><f>1+1</f></c>"},"corrected":false},{"label":"corrected base","input":{"kind":"text","value":"=1+1"},"expected":{"fragment":"<c t=\"inlineStr\"><is><t>=1+1</t></is></c>"},"corrected":true},{"label":"ordinary text retains declared type","input":{"kind":"text","value":"Ada"},"expected":{"fragment":"<c t=\"inlineStr\"><is><t>Ada</t></is></c>"},"corrected":true},{"label":"genuine negative numeric cell","input":{"kind":"number","value":-2},"expected":{"fragment":"<c><v>-2</v></c>"},"corrected":true},{"label":"literal XML text is escaped","input":{"kind":"text","value":"A<&>"},"expected":{"fragment":"<c t=\"inlineStr\"><is><t>A<&></t></is></c>"},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
下次載入前核邊界
Ada 仍是文字,真正 −2 仍是數字,A<&> 則把 XML 特殊字元轉義以保原文。
| 情況 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 普通文字格 | {"kind":"text","value":"Ada"} | {"fragment":"<c t=\"inlineStr\"><is><t>Ada</t></is></c>"} |
| 真正負數格 | {"kind":"number","value":-2} | {"fragment":"<c><v>-2</v></c>"} |
| 含 XML 特殊字元的原文 | {"kind":"text","value":"A<&>"} | {"fragment":"<c t=\"inlineStr\"><is><t>A<&></t></is></c>"} |
此處開頭等號應否建立公式?
查看參考答案
不應,來源類型是文字。把 =1+1 放在行內字串格保留,不改成公式 1+1。