跳至內容
Astera Technology

收據參考太長,也不能截掉尾段

按已訂字格要求分行,同時保住整個參考。

下載完整個案資料及參考答案 ↓

訂判斷及所需輸入

本例每行二十個 ASCII 字格,明准長參考每二十字分行。A 至 Y 共二十五字,須分二十字首行及 UVWXY。截成一行就丟尾五字。

已填本地測試工作表
情況輸入 JSON
原例測試{"cells":20,"reference":"ABCDEFGHIJKLMNOPQRSTUVWXY"}
下載可編輯 CSV ↓

跑所附比較

程序生成 PDF,抽出真正參考行,再把分行合起對原文。字格上限由本例訂,不表示真實字形或打印機的字寬都相同。

錯誤及所需輸出
路徑輸出 JSON
錯誤路徑{"lines":["ABCDEFGHIJKLMNOPQRST"],"complete":false}
所需路徑{"lines":["ABCDEFGHIJKLMNOPQRST","UVWXY"],"complete":true}
下載可編輯 CSV ↓
Node24.14.1 程序;須 Playwright1.63 Chromium 及 PDF.js6.4.299
import assert from 'node:assert/strict';
const smallWhole=(x,max)=>Number.isSafeInteger(x)&&x>=0&&x<=max;
import {createRequire} from 'node:module';
import {pathToFileURL} from 'node:url';
const htmlEscape=s=>String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
async function withPage(action,options={}){
  const require=createRequire(import.meta.url);const {chromium}=require('playwright');
  const browser=await chromium.launch({headless:true});
  try{const context=await browser.newContext(options);const page=await context.newPage();
    const requests=[];await page.route('**/*',route=>{requests.push(route.request().url());return route.abort();});
    return await action(page,context,requests);
  }finally{await browser.close();}
}
async function pdfObservation(html){
  const bytes=await withPage(async page=>{await page.setContent(html);return page.pdf({preferCSSPageSize:true,printBackground:true});});
  const require=createRequire(import.meta.url);
  const {getDocument}=await import(pathToFileURL(require.resolve('pdfjs-dist/legacy/build/pdf.mjs')).href);
  const loadingTask=getDocument({data:Uint8Array.from(bytes),useSystemFonts:true,disableFontFace:true});
  try{const document=await loadingTask.promise;const pages=[];for(let n=1;n<=document.numPages;n++){
    const page=await document.getPage(n);const content=await page.getTextContent();
    pages.push(content.items.filter(x=>typeof x.str==='string'&&x.str).map(x=>({text:x.str,x:x.transform[4],y:x.transform[5]})));
  }return {pageCount:document.numPages,pages};}finally{await loadingTask.destroy();}
}
const printStyle='<style>@page{size:100mm 100mm;margin:10mm}body{margin:0;font:10px Arial}p{margin:0}</style>';

const run=async function run(i,corrected=true){
    if(!smallWhole(i.cells,20)||i.cells<1||typeof i.reference!=='string'||!/^[\x21-\x7E]{1,40}$/.test(i.reference))return {held:true};
    const lines=corrected?Array.from({length:Math.ceil(i.reference.length/i.cells)},(_,n)=>i.reference.slice(n*i.cells,(n+1)*i.cells)):[i.reference.slice(0,i.cells)];
    const out=await pdfObservation(printStyle+'<pre style="margin:0;font:10px Courier;line-height:5mm">'+htmlEscape(lines.join('\n'))+'</pre>');
    const extracted=out.pages.flat().map(x=>x.text);return {lines:extracted,complete:extracted.join('')===i.reference};
  };
const cases=[{"input":{"cells":20,"reference":"ABCDEFGHIJKLMNOPQRSTUVWXY"},"corrected":false,"expected":{"lines":["ABCDEFGHIJKLMNOPQRST"],"complete":false}},{"input":{"cells":20,"reference":"ABCDEFGHIJKLMNOPQRSTUVWXY"},"corrected":true,"expected":{"lines":["ABCDEFGHIJKLMNOPQRST","UVWXY"],"complete":true}},{"input":{"cells":20,"reference":"ABCDEFGHIJKLMNOPQRST"},"corrected":true,"expected":{"lines":["ABCDEFGHIJKLMNOPQRST"],"complete":true}},{"input":{"cells":null,"reference":"A"},"corrected":true,"expected":{"held":true}}];
for(const test of cases){const actual=await run(test.input,test.corrected);assert.deepEqual(actual,test.expected);console.log(actual);}
下載可執行例子 ↓

按邊界依據作判斷

剛好二十字,只留一行仍完整;字格配額未知,生成收據前先停。

  1. 核已訂字格要求
  2. 分行但不刪字
  3. 抽行再核完整參考

實體打印機的格點或字寬規則須另提供。

可編輯邊界輸入及結果
條件輸入 JSON預期輸出 JSON
參考剛好二十字格{"cells":20,"reference":"ABCDEFGHIJKLMNOPQRST"}{"lines":["ABCDEFGHIJKLMNOPQRST"],"complete":true}
字格配額欠缺{"cells":null,"reference":"A"}{"held":true}
下載可編輯 CSV ↓

原例第二行必須保哪段?

查看參考答案

UVWXY。首行 ABCDEFGHIJKLMNOPQRST,兩行合起才還原二十五字。

例子檔案

相關資源