我如何在 n8n 中以 PDF 格式提取資料表。表格有很多資料。
嘿 Azizul,
我可以幫助你在 n8n 中以高精度從 PDF 檔案提取大型表格,無論 PDF 是數位還是掃描版本,並將資料結構化為 Excel、Google Sheets、Airtable 或你的資料庫。
• 高效解析 PDF 表格
• 在需要時使用 OCR 處理掃描的 PDF
• 清理和結構化提取的資料
• 匯出到你偏好的目標
• 自動化整個工作流程
嘿 Azizul,當然可以!這主要取決於你的 PDF 看起來如何,所以先問幾個問題:
- 所有文件的表格結構都相同,還是每份 PDF 都不同?
- 這些 PDF 是數位生成的還是掃描的?
- 大約有多少份文件或多少行數據,你所說的「很多數據」具體是什麼意思?
- 這些數據有多敏感?
根據答案的不同,有不同的方法。一個經典的方法是:
- OCR,讀取數據
- 處理數據(可以用腳本完成)
- 保存數據
我們也可以討論一下:預約
n8n 有一個內建的「從 PDF 提取」功能,但它只提取純文字,不包括表格結構。這意味著對於任何有實際欄位和列的內容,它都會出現問題。根據您的 PDF 類型,以下是幾種方法:
對於具有可選文字的普通 PDF,您可以將其通過使用 pdf-parse 或 pdf-table-extractor 等程式庫的代碼節點進行處理。您可以通過 HTTP 要求節點呼叫專門的表格提取 API,然後解析傳回的 JSON/CSV。
如果是掃描的影像型 PDF:您首先需要進行 OCR,例如 AWS Textract、Google Document AI 或 Azure Form Recognizer 都具有不錯的表格偵測模式,您可以直接從 HTTP 要求節點呼叫。Textract 的「分析文件」搭配 TABLES 功能類型可能是最可靠的。
感謝Loic Lavachy的電郵。實際上我提取了pdf檔案,但當我將數據發送到工作表時,只有一行。我不知道為什麼沒有從pdf表格中保存所有數據。好的,我給出答案:1. 數據表結構將保持相同。2. 所有PDF都是數字化創建的。3. 請檢查附加的樣本文件。文件將保持相同。但不是一次很多數據。4. 如果Pdf檔案是孟加拉語,那麼應該怎麼辦?我附上了另一個challan樣本文件以便更好地理解。
(attachments)
Data.pdf (17.9 KB)
challan.pdf (60.2 KB)
感謝 Sachin Karma 的郵件。我很高興得知你能幫助我。實際上,我可以使用 mistral 從 pdf 數據表文件中提取數據。但當它將數據保存到工作表時,我只看到添加了一行,而不是全部。我不知道為什麼。我給你發送了一個示例數據表 pdf 文件。請查看附件。
我的另一個問題是我還有一個孟加拉語的 pdf 文件。我也附加了那個。如果是孟加拉語文件,我應該怎麼做?
Azizul
歡迎 @Azizul_Khan!
單列問題幾乎總是因為 Mistral 將整個表格作為單個 JSON 陣列返回到單個項目中,所以 Sheets 只能看到項目 1。在 Mistral 節點之後立即添加「分割輸出」節點(或帶有 return items 的程式碼節點),將該陣列欄位分割成單獨的項目(每個表格列一個),然後再發送到 Google Sheets。首先直接檢查 Mistral 節點的 JSON 輸出,確認列是否嵌套在「rows」或「table」之類的單個欄位下。對於孟加拉語 PDF,Mistral OCR 確實支援非拉丁文字,但要仔細檢查提取的文字編碼,如果文字返回時出現亂碼,請嘗試在請求中明確設定語言提示(如果該模型支援的話),否則將孟加拉語文件改用 Google Document AI 處理,因為它的表格和語言檢測對非拉丁文字的可靠性更高。
感謝 Jay Nguyen 先生的電郵。很抱歉我沒有理解您寶貴的建議。實際上我是 n8n 和 json 的新手。如果我能看到任何視頻的話就能理解。但如果可能的話,您能否提供一個詳細的示例,說明我如何能將所有原始數據導入到表格中,這樣我就能嘗試。我附上了示例檔案,請幫我查一下。
阿齊祖爾。
嘿 Azizul,
我再看了一遍 PDF,並在附件中上傳了一個示例工作流程(JSON),展示了一種可能的方法。
要讓它在你的系統上運作,你需要:
- 自己建立認證資訊(Google Drive 和 LLM,目前是 Mistral)
- 指定存放 PDF 的資料夾路徑
你當然可以更改輸入方式,例如改用表單上傳而不是 Google Drive。LLM 也可以換成其他模型。前提是 PDF 必須是數位生成的,對於掃描文件,需要先進行 OCR 處理。
關於孟加拉語的例子:該腳本目前只是按行分割文字並將其儲存為 JSON,這還不是像英文分支那樣的結構化提取。根據該表格的具體結構方式,還需要進一步擴展。
一般來說,關於 PDF 和資料保護:整個過程也可以直接通過 LLM 運行,但這裡涉及敏感資料(電郵和地址)。如果沒有與歐盟供應商簽訂數據處理協議且缺乏適當的法律依據,我建議不要未經檢查就將這些資料輸入 LLM。由於姓名和父名無法乾淨地自動分離,我只將這兩個欄位傳遞給 LLM,這在法律上仍然是一個灰色地帶,應該在具體情況下進行審查。
為了最後的完善,我建議使用 Claude Code 或其他 LLM 直接在工作流程上繼續工作。如有需要,也歡迎直接聯絡我。
pdf-tin-table-extraction.json(17.3 KB)
如果 Mistral 已經在提取 PDF,但 Google Sheets 只獲得一行,通常的問題是提取結果仍然是一個包含表格/陣列的 n8n 項目。Google Sheets 會每個輸入項目附加一行,所以你需要在 Mistral 和 Sheets 之間放置一個 Code 節點,將提取的表格轉換為多個項目。
對於具有相同結構的數位建立的 PDF,我會使用這個流程:
- Form Trigger / Gmail / 手動上傳 — 接收 PDF 二進位檔案。
- Mistral OCR / 文件提取 — 返回 Markdown 或文本。
- Code 節點 — 解析 Markdown 表格並為每個 PDF 行返回一個項目。
- Google Sheets → 附加行 — 從每個項目對應欄位。
如果 Mistral 返回一個 Markdown 表格,例如 | name | amount | date |,請嘗試在 OCR 節點後使用這個 Code 節點:
const markdown = $json.markdown || $json.text || $json.output || '';
const tableLines = markdown
.split('\n')
.map((line) => line.trim())
.filter((line) => line.startsWith('|') && line.endsWith('|'));
if (tableLines.length < 2) {
throw new Error('No Markdown table found in OCR output');
}
const splitRow = (line) =>
line
.split('|')
.slice(1, -1)
.map((cell) => cell.trim());
const headers = splitRow(tableLines[0]);
const dataRows = tableLines
.slice(1)
.filter((line) => !/^\|?\s*:?-{3,}/.test(line.replace(/\|/g, '').trim()));
return dataRows.map((line) => {
const cells = splitRow(line);
const row = {};
headers.forEach((header, index) => {
row[header || `column_${index + 1}`] = cells[index] || '';
});
return { json: row };
});
然後在 Google Sheets 中,使用來自傳入項目的欄位進行附加。不要將整個 OCR 結果放入一個儲存格中,也不要將所有行包裝在單個 rows 陣列內,除非你在傳送到 Sheets 之前再次將其拆分。
對於孟加拉語 PDF:如果 PDF 是數位產生/可選擇的文本,孟加拉語應該通過 Unicode 傳遞並正確儲存到 Google Sheets。如果是掃描/影像型 PDF,請使用支援孟加拉語或語言提示的 OCR 提供商,然後在 Sheets 之前執行同樣的「一個提取的行 = 一個 n8n 項目」步驟。
透明說明:我使用 FlowForge AI 建立了這個行分割藍圖,並針對你「Mistral 提取但 Sheets 只獲得一行」的問題進行了改編。
感謝您的電郵。是的,Mistral 會傳回 Markdown 表格,例如 | name | amount | date |。我應該將這段程式碼貼到 n8n 中的提取資訊節點嗎?還是我應該在其他地方貼上這段程式碼?
嗨 Azizul,
感謝你提供的樣本;它們讓問題變得清楚了。
兩個解答:
- 只保存一行
這不是 Mistral 的問題——你的提取實際上正常運作;Mistral 正在讀取完整的表格。問題出在寫入 Google Sheets 的步驟。現在所有行都作為一個項目一起到達,所以「新增行」步驟只運行一次並寫入單一行。
修正:在 Google Sheets 步驟之前,添加一個步驟來將行拆分成單獨的項目——
- Make.com:添加一個指向行陣列的「Iterator」,然後在它後面保留「新增行」。這樣它就會每行運行一次。
- n8n:在行欄位上添加一個「Split Out」節點,然後在它後面添加「追加行」。
還要確保 Mistral 將表格返回為 JSON 列表(每行一個物件),而不是一個文本塊——否則沒有什麼可拆分的。
- 孟加拉語 PDF
你的孟加拉語 challan 是數字創建的,但其文本層已損壞——如果你直接提取文本,你會得到錯誤的/亂碼字母。所以對孟加拉語文件不要先提取文本。將 PDF 頁面本身發送給 Mistral OCR(作為圖像/文件)。Mistral OCR 讀取圖片並很好地支持孟加拉語,所以你會得到正確的孟加拉文本。
一個說明:challan 是不同的佈局——一份有標題和總計的報告,不像數據文件那樣是平坦的表格,所以它需要與你的英文文件不同的列映射。