_parse.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. const fs = require('fs');
  2. const zlib = require('zlib');
  3. const buf = fs.readFileSync('docs/工作考核对象.docx');
  4. let pos = 0; const sig = 0x04034b50; let xml = null;
  5. while (pos < buf.length - 4) {
  6. if (buf.readUInt32LE(pos) !== sig) { pos++; continue; }
  7. const method = buf.readUInt16LE(pos + 8);
  8. const compSize = buf.readUInt32LE(pos + 18);
  9. const nameLen = buf.readUInt16LE(pos + 26);
  10. const extraLen = buf.readUInt16LE(pos + 28);
  11. const name = buf.toString('utf8', pos + 30, pos + 30 + nameLen);
  12. const dataStart = pos + 30 + nameLen + extraLen;
  13. const dataEnd = dataStart + compSize;
  14. if (name === 'word/document.xml') { let d = buf.slice(dataStart, dataEnd); if (method===8) d=zlib.inflateRawSync(d); xml = d.toString('utf8'); }
  15. pos = dataEnd;
  16. }
  17. function txt(s){let r='';const re=/<w:t\b[^>]*>([\s\S]*?)<\/w:t>/g;let m;while((m=re.exec(s))!==null)r+=m[1];return r;}
  18. function findPara(s, from){let idx=s.indexOf('<w:p',from);while(idx!==-1){const c=s[idx+4];if(c===' '||c==='>'||c==='\t'||c==='\n')return idx;idx=s.indexOf('<w:p',idx+5);}return -1;}
  19. const blocks=[]; let i=0; const body=xml;
  20. while(i<body.length){
  21. const tIdx=body.indexOf('<w:tbl>',i);
  22. const pIdx=findPara(body,i);
  23. if(tIdx===-1&&pIdx===-1)break;
  24. if(pIdx!==-1&&(tIdx===-1||pIdx<tIdx)){const end=body.indexOf('</w:p>',pIdx);blocks.push({type:'p',text:txt(body.substring(pIdx,end+6))});i=end+6;}
  25. else {const end=body.indexOf('</w:tbl>',tIdx);blocks.push({type:'tbl',raw:body.substring(tIdx,end+8)});i=end+8;}
  26. }
  27. const out=[];let ti=0;
  28. for(let b=0;b<blocks.length;b++){
  29. if(blocks[b].type!=='tbl')continue;ti++;
  30. const pre=[];for(let k=b-1;k>=0;k--){if(blocks[k].type==='tbl')break;if(blocks[k].text.trim())pre.unshift(blocks[k].text);}
  31. out.push('\n=== TABLE '+ti+' ===');
  32. out.push('PRE: '+JSON.stringify(pre));
  33. const rowRe=/<w:tr[ >]([\s\S]*?)<\/w:tr>/g;let rm;
  34. while((rm=rowRe.exec(blocks[b].raw))!==null){
  35. const cellRe=/<w:tc[ >]([\s\S]*?)<\/w:tc>/g;let cm;const cells=[];
  36. while((cm=cellRe.exec(rm[1]))!==null)cells.push(txt(cm[1]).trim());
  37. out.push(cells.join(' | '));
  38. }
  39. }
  40. fs.writeFileSync('docs/_parsed.txt', out.join('\n'), 'utf8');
  41. console.log('tables:',ti);