print_pdf.js 模組整合說明、main_flow.js 修改 diff、命名規則規格、Excel 欄位格式
- const { takeScreenshot, isScreenshotExists } = require('./screenshot'); + const { printToPdf, isPdfExists } = require('./print_pdf');
投票前的過濾迴圈,用來跳過已有 PDF 的公司
for (const meeting of meetings) { - if (isScreenshotExists(saveDir, idNumber, meeting.stockCode, flat)) continue; + if (isPdfExists(saveDir, idNumber, meeting, flat)) { + sendLog(`已有 PDF,略過:${meeting.stockCode}`); + continue; + } // ... 執行投票(不變) }
isPdfExists 接受整個 meeting 物件(需含 stockCode 與 meetingDate),舊版只傳 stockCode 字串,注意差異。// 投票成功後 - const screenshotPath = await takeScreenshot( - webContents, saveDir, idNumber, meeting.stockCode, meeting.companyName, flat - ); - sendLog(`截圖完成:${screenshotPath}`); + const pdfPath = await printToPdf( + webContents, // BrowserView.webContents(停在投票確認頁) + meeting, // { stockCode, meetingDate, ... } + saveDir, // 使用者選擇的儲存根目錄 + idNumber, // 身分證字號 + { flat } // 沿用目錄結構設定 + ); + sendLog(`PDF 已儲存:${pdfPath}`);
print_pdf.js 需要 meeting.meetingDate 才能產生 MMDD 日期碼。
若集保頁面上有顯示「股東會日期」欄位,voting.js 爬清單時應一併取出:
const meetings = await safeExecute(webContents, ` Array.from(document.querySelectorAll('.meeting-row')).map(row => ({ stockCode: row.querySelector('.stock-code')?.textContent?.trim(), companyName: row.querySelector('.company-name')?.textContent?.trim(), meetingDate: row.querySelector('.meeting-date')?.textContent?.trim(), // ↑ 對應集保頁面「股東會日期」的 CSS selector,依實際 DOM 調整 })) `); // meetingDate 若 null,getMeetingDateCode() 自動 fallback 為今天的 MMDD
meetingDate 傳 null 即可,print_pdf.js 會自動使用台灣時間今日的 MMDD 作為 fallback。格式:{MMDD}_{會員代號}_{股票代號}.pdf
| 欄位 | 長度 | 演算法 / 來源 | 範例 |
|---|---|---|---|
| MMDD 開會日期 |
4碼 | 月份(補零2碼) + 日期(補零2碼) 支援格式: YYYY-MM-DD、YYYYMMDD、MM-DD、MMDD |
0215(2月15日)0601(6月1日) |
| 會員代號 memberId |
6碼 | SHA-256(身分證字號.trim().toUpperCase()).slice(0,6).toUpperCase()確定性:同一身分證永遠相同,不可逆推 |
51FF20(A123456789)30DCC4(B987654321) |
| 股票代號 stockCode |
4~6碼 | 集保系統原始代號,直接使用 | 2330(台積電) |
0215_51FF20_2330.pdf ← 2月15日 · A123456789 · 台積電(2330)
| 函式 | 參數 | 回傳 | 說明 |
|---|---|---|---|
printToPdf(webContents, meetingInfo, saveDir, idNumber, [options]) |
見下方 | Promise<string> 完整路徑 |
對投票確認頁執行 Electron printToPDF,儲存 PDF |
isPdfExists(saveDir, idNumber, meetingInfo, [flat]) |
同上 | boolean |
檢查 PDF 是否已存在(智慧補邏輯) |
generateMemberId(idNumber) |
string |
string 6碼 |
由身分證字號確定性產生會員代號 |
getMeetingDateCode(meetingInfo) |
object |
string MMDD |
解析各種日期格式,回傳 MMDD |
parseMmdd(raw) |
string|Date |
string MMDD |
日期字串解析,支援多種格式 |
// printToPdf 第五個參數 options(可選) { flat: false, // true=扁平目錄 / false=依身分證分層(預設) landscape: false, // true=橫向A4 / false=直向A4(預設) }
print_pdf.js 與 main_flow.patch.js 屬於 Electron 桌面版的程式碼,放入 src/automation/ 目錄下使用。其餘 .html 頁面在瀏覽器中直接開啟即可。