PDF导出大文本处理:如何用PHP/JS替换生成结构化HTML表格
实现方案
完全可以用JavaScript实现该需求,不需要写固定数量的replace规则,通过正则匹配+反向拆分字段的逻辑可以适配1~50条任意数量的条目,处理逻辑如下:
- 用正则匹配所有
数字.开头的条目,自动拆分所有行数据,不需要提前知道条目总数 - 由于除DESCRIPTION外的6个字段格式高度固定(均为数字/带括号数字/数字+单位格式),从后往前拆分字段即可精准提取每个列的值,同时自动将散落在ACV后的描述内容补回DESCRIPTION列
完整JS代码示例如下:
// 原始文本 const rawText = `DESCRIPTION QUANTITY UNIT PRICE TAX RCV DEPREC. ACV 1. Remove 3 tab - 25 yr. - composition shingle roofing - 21.25 SQ 52.83 0.00 1,122.64 (0.00) 1,122.64 incl. felt 2. 3 tab - 25 yr. - composition shingle roofing - incl. felt 24.67 SQ 186.84 199.43 4,808.77 (0.00) 4,808.77 3. R&R Drip edge 196.95 LF 2.33 16.27 475.16 (0.00) 475.16 4. Asphalt starter - universal starter course 100.58 LF 1.31 3.67 135.43 (0.00) 135.43 5. Ice & water barrier 118.94 SF 1.15 4.34 141.12 (0.00) 141.12 6. R&R Roof vent - turtle type - Metal 5.00 EA 51.09 6.55 262.00 (0.00) 262.00 7. R&R Flashing - pipe jack 3.00 EA 38.63 2.95 118.84 (0.00) 118.84 8. R&R Rain cap - 6" 2.00 EA 36.80 3.40 77.00 (0.00) 77.00 9. R&R Ridge cap - composition shingles 77.58 LF 4.67 7.04 369.33 (0.00) 369.33 10. Digital satellite system - Detach & reset 1.00 EA 31.40 0.00 31.40 (0.00) 31.40 11. Digital satellite system - alignment and calibration 1.00 EA 94.19 0.00 94.19 (0.00) 94.19 only 12. R&R Flashing - pipe jack - split boot 1.00 EA 76.00 3.76 79.76 (0.00) 79.76 13. R&R Gutter / downspout - aluminum - up to 5" 152.58 LF 7.13 49.56 1,137.45 (0.00) 1,137.45`; // 切掉开头表头,拆分所有条目 const entryPart = rawText.replace(/^DESCRIPTION QUANTITY UNIT PRICE TAX RCV DEPREC\. ACV /, ''); const entries = entryPart.split(/(?=\d+\. )/).filter(Boolean); // 组装表格 let tableHtml = `<table> <tr> <th>DESCRIPTION</th> <th>QUANTITY</th> <th>UNIT PRICE</th> <th>TAX</th> <th>RCV</th> <th>DEPREC.</th> <th>ACV</th> </tr>`; entries.forEach(entry => { // 从后往前拆分字段,匹配规则:ACV(数字) → DEPREC(带括号数字) → RCV(数字) → TAX(数字) → UNIT PRICE(数字) → QUANTITY(数字+空格+单位) const reg = /(.*?)\s+([\d,]+\.[\d]{2})\s+(\(\d+\.\d+\))\s+([\d,]+\.[\d]{2})\s+([\d,]+\.[\d]{2})\s+([\d,]+\.[\d]{2})\s+(\d+\.\d+\s+[A-Za-z]+)\s*(.*)/; const match = entry.match(reg); if (match) { const desc = (match[1] + ' ' + match[8]).trim(); const qty = match[7]; const unitPrice = match[6]; const tax = match[5]; const rcv = match[4]; const deprec = match[3]; const acv = match[2]; tableHtml += ` <tr> <td>${desc}</td> <td>${qty}</td> <td>${unitPrice}</td> <td>${tax}</td> <td>${rcv}</td> <td>${deprec}</td> <td>${acv}</td> </tr>`; } }); tableHtml += '</table>'; // 输出表格,可直接插入到页面DOM中 console.log(tableHtml);
如果需要用PHP实现,也可以套用相同的正则逻辑,比你原来逐个写replace的方案可维护性高很多,不需要适配不同的条目数量。
内容的提问来源于stack exchange,提问作者jQuery
相关产品推荐
相关产品推荐

