Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Current events
Recent changes
Random page
Help
Categories
LemonWiki共筆
Search
Search
Appearance
Log in
Personal tools
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
PDF Table Parsing in Mandarin
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
PDF 表格解析技術筆記 解析 PDF 表格時,通常無法只依賴 <code>pdfplumber.extract_tables()</code>、Camelot、Tabula 或類似函式庫輸出的原始結果。由於 PDF 主要是以版面配置為核心的格式,而非結構化資料格式,實務上往往需要額外的規則、狀態管理與後處理步驟,才能產出穩定且可用的資料集。 {{LanguageSwitcher | content = [[PDF Table Parsing | EN]], [[PDF Table Parsing in Mandarin | 漢字]] }} === 不同解析工具的比較 === # [https://github.com/jsvine/pdfplumber pdfplumber]:需要撰寫程式處理資料。 # [https://www.xpdfreader.com/pdftotext-man.html pdftotext] 搭配 <code>-layout</code> 選項:缺點是透過空白字元對齊各欄,而非擷取成真正的結構化表格。 # [https://jina.ai/ jina.ai 解析工具]:缺點是透過空白字元對齊各欄,而非擷取成真正的結構化表格。 === 1. 術語說明 === '''解析器(Parser)''' <code>parser</code> 是負責解析 PDF 內容,並將其轉換為結構化資料的程式。它通常不只是讀取文字或表格,還需要辨識章節、表格類型、欄位位置、資料列、接續內容,以及來源中繼資料。 '''資料紀錄(Record)''' <code>record</code> 是解析器產出的一筆標準化資料。 PDF 中的一列不一定對應一筆資料紀錄。同一筆紀錄可能分散在多列、跨頁接續,或需要繼承父列的資訊後才算完整。 '''章節/子章節(Section / Subsection)''' <code>section</code> 與 <code>subsection</code> 分別指文件中的章節與子章節。 這些欄位通常用來描述資料的來源脈絡,例如某筆紀錄來自哪個章節或表格區塊。 '''表格類型(Table Type)''' <code>table_type</code> 是由解析器自行定義的表格類型標籤,用來表示目前表格屬於哪一種資料結構。 例如: * <code>summary_table</code>:摘要表 * <code>detail_table</code>:明細表 * <code>parent_child_table</code>:父子關係表 * <code>cross_reference_table</code>:交叉參照表 * <code>unknown_table</code>:未知類型表格 <code>table_type</code> 的用途,是協助解析器判斷應套用哪一組解析規則。 它不是 PDF 的內建欄位,也不是 <code>pdfplumber</code>、Camelot 或 Tabula 會自動提供的資訊。 '''表格結構定義(Table Schema)''' <code>table schema</code> 指特定表格類型的欄位結構與解析規則。 通常包含欄位數量、欄位順序、標準化欄位名稱、欄位別名、必填欄位、允許空值的欄位,以及是否需要特殊的接續處理或父子列處理。 在 PDF 表格解析中,<code>table schema</code> 不一定是資料庫綱要,而是解析器用來對齊與標準化表格資料的一組規則。 '''欄位對應(Column Mapping)''' <code>column mapping</code> 指將 PDF 原始欄位對應至標準化欄位的過程。 例如,不同文件可能使用「項目名稱」、「物件名稱」或「標的名稱」等欄名,但在輸出資料時,都可以統一為 <code>item_name</code>。 '''別名對應(Alias Mapping)''' <code>alias mapping</code> 指欄名別名的對照表。 由於 PDF 表格的欄名經常因版本、格式或填報單位而異,解析器需要將多種欄名對應至同一個標準化欄位。 '''向下填補(Forward-Fill)''' <code>forward-fill</code> 指讓後續資料列繼承前面資料列欄位值的處理方式。 在父子列結構中,父列可能只出現一次,後續子列則省略重複資訊。此時,解析器需要將父列資訊填入各個子列。 '''父列/子列(Parent Row / Child Row)''' <code>parent row</code> 是提供主要分類、群組或摘要資訊的資料列。 <code>child row</code> 是隸屬於某個父列的明細資料列。 PDF 表格經常由父列列出主要資訊,子列則只列出明細項目。如果未處理父子列關係,輸出資料可能會遺失必要的脈絡。 '''跨頁接續(Cross-Page Continuation)''' <code>cross-page continuation</code> 指同一筆資料紀錄被拆開,並接續至下一頁的情況。 名稱、說明文字、分類欄位、備註或其他較長的欄位,都可能發生這種情況。 處理跨頁接續時,需要判斷下一頁的文字是否屬於上一頁尚未完成的紀錄,而非直接將其視為新的資料列。 '''中繼資料(Metadata)''' <code>metadata</code> 指用來描述資料來源與解析狀態的輔助資訊。 常見欄位包括 <code>page</code>、<code>table_index</code>、<code>table_type</code>、<code>section</code>、<code>subsection</code>、<code>source_file</code>、<code>raw_row</code> 與 <code>parse_warning</code>。 中繼資料有助於除錯、稽核、資料溯源與資料品質檢查。 === 2. 章節辨識需要保留跨頁狀態 === PDF 文件中的章節、子章節與表格分類資訊,不一定會在每一頁重複出現。因此,解析器需要保留目前的 <code>section</code>、<code>subsection</code> 或其他文件層級的脈絡,並在後續頁面沿用。 常見情境包括: * 接續頁可能只有表格內容,沒有重複顯示章節標題。 * 目錄、摘要或說明頁可能同時出現多個章節名稱。如果解析器只檢查頁面是否包含特定關鍵字,就可能誤判頁面所屬章節。 * 章節標題可能因版面差異而使用不同標點或間距,例如全形或半形括號、頓號、冒號、全形句點或多餘空白。 * 切換章節、子章節或表格類型時,必須清除上一個表格沿用的狀態,避免將資料錯誤帶入下一個區塊。 建議結合文字位置、標題樣式與上下文狀態來判斷章節,而非只依賴整頁的關鍵字比對。 === 3. 同一章節可能包含多種表格結構 === 同一章節可能包含多種類型的表格。如果解析器只根據章節名稱決定欄位對應方式,就可能造成欄位錯置。 解析每個表格時,解析器應先檢查表頭或前幾列,確認下列資訊: * <code>table_type</code> * 欄位數量 * 欄位順序 * 標準化欄位名稱 * 是否存在父子列關係 * 是否需要特殊的接續處理 欄名也可能使用別名、縮寫,或隨文件版本採用不同用語。例如,「項目名稱」、「物件名稱」與「標的名稱」,在不同文件中可能代表相近的欄位。因此,實作時應維護一份別名對照表,將不同欄名統一對應至一致的欄位。 === 4. 父子列關係需要支援向下填補 === 部分 PDF 表格會由父列列出主要資訊,後續子列則只列出明細欄位。例如,父列可能包含主要分類、群組名稱、案件編號或摘要資訊,子列則只列出子項編號、明細名稱或詳細內容。 這類表格需要支援向下填補,讓子列繼承父列的欄位值。 設計時應考量: * 父列狀態應依 <code>section</code>、<code>subsection</code> 與 <code>table_type</code> 等脈絡分別管理。 * 父列狀態可能需要跨頁保留。 * 不應只使用單一文字欄位作為父列識別依據,因為不同父列可能具有相同或相近的名稱。 * 回填資料時,至少應考量章節、子章節、表格類型與父列識別碼。 章節或表格改變時,應明確重設父列狀態,避免將上一個表格的資料帶入下一個表格。 === 5. 跨頁接續不只是處理重複表頭 === PDF 表格跨越多頁時,資料可能以各種方式被拆開。解析器若只處理下一頁重複出現的表頭,通常不足以應付實際文件。 常見的跨頁接續情況包括: * 下一頁第一列只包含上一頁某個欄位的後半段內容。 * 名稱、分類、說明文字或備註被拆到不同頁面。 * 下一頁開頭先出現多列表頭,接著才延續上一頁尚未完成的紀錄。 * 同一列同時出現接續文字與新資料列的識別碼。 * 空白欄被壓縮,導致欄位位置偏移。 * 表格框線、換行或 OCR 辨識結果,將原本的一列拆成多列。 因此,跨頁處理應保留原始欄位位置,不宜過早移除空白欄。必要時,解析器應結合欄位座標、欄位索引、識別碼格式與前一筆紀錄的狀態,判斷接續片段屬於哪個欄位。 合併接續內容時,也應依文字類型採用不同方式: * 中文文字片段通常可以直接串接。 * 英文文字片段通常需要插入空白。 * 多值欄位、分類欄位或備註,可能需要保留換行、列舉符號或分隔符號。 * 數值欄位應避免誤將文字片段串接在一起。 === 6. 表頭、註解與資料列應分階段辨識 === PDF 表格經常包含表頭、單位說明、註解、小計、總計、頁尾或空白列。如果解析器將所有含有文字的列都視為資料列,就很容易產生錯誤紀錄。 建議將解析流程分成下列階段: # 等待表頭關鍵字出現。 # 辨識表頭區域與欄名。 # 判斷資料列的起始位置。 # 處理一般資料列。 # 處理跨頁接續內容。 # 排除註解、單位說明、小計、總計與頁尾。 # 輸出標準化紀錄。 缺漏欄位可以填入 <code>null</code>。但如果欄位已經偏移,解析器就不能直接依壓縮後陣列的順序套用表格結構定義,否則可能造成整列資料錯置。 === 7. 中繼資料應儲存在每筆紀錄中 === 解析 PDF 表格時,除了擷取資料本身,也應保留來源脈絡。這些中繼資料對除錯、稽核、資料溯源,以及後續的扁平化輸出都很重要。 建議每筆紀錄至少包含: * <code>page</code>:頁碼 * <code>table_index</code>:表格索引 * <code>table_type</code>:表格類型 * <code>section</code>:章節 * <code>subsection</code>:子章節 * <code>source_file</code>:來源檔案 * <code>raw_row</code>:原始資料列 * <code>parse_warning</code>:解析警告 將中繼資料寫入每筆紀錄,有助於在 JSON 扁平化為 CSV、匯入資料庫,或以單筆紀錄傳遞時,避免遺失脈絡。 如果文件本身包含年度、季度、期別、版本、批次或分類資訊,也應明確保留,避免混用不同批次的資料。 === 8. 實作建議 === PDF 表格解析器可以採用分層設計,將擷取、分類、清理、狀態管理、標準化與驗證分開處理。 建議流程如下: # 從 PDF 擷取文字、表格與座標資訊。 # 辨識頁面所屬章節與表格區塊。 # 根據表頭關鍵字判斷 <code>table_type</code>。 # 套用對應的表格結構定義與欄名別名對照表。 # 辨識資料列、父列、子列與接續列。 # 管理跨頁狀態、父列狀態與其他文件層級狀態。 # 將資料轉換為標準化紀錄。 # 加入來源中繼資料。 # 執行迴歸檢查與資料品質檢查。 # 輸出 JSON、CSV 或可直接匯入資料庫的紀錄。 這種設計可以降低個別規則與特定 PDF 版面過度耦合的風險,也能在文件格式改變時,更容易只調整受影響的部分。 [[Category: Tool]] [[Category: PDF]] [[Category: Revised with LLMs]]
Summary:
Please note that all contributions to LemonWiki共筆 are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see
LemonWiki共筆:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Template:LanguageSwitcher
(
edit
)