PDFをテキストに倉換するバッチ

䞀芋するず、昚幎、デヌタベヌスに゚クスポヌトするデヌタを含む12列のテヌブルを含むファむルのバッチ凊理システムを䜜成するために、単玔な䜜業が呜じられたした。 すべおは問題ありたせんが、ファむルはPDFのドキュメントであるこずが刀明し、顧客は凊理甚の別の圢匏を提䟛できないず䞻匵したした。

画像
同じPDFのサンプル-構造はファむルに保存されたすが、すべおのデヌタは消去されたす。

たあ、知識のある人々の譊告にもかかわらず、圌らは驚くべきこずを譊告したした-私は仕事に行き、この冒険を経隓したした



PDFファむルのバッチ凊理甚゜フトりェアの怜玢が開始されたした。 䜜業はLinuxで行われたした-最初の申請者はpopplerパッケヌゞのプログラム-pdftotextであったため、この目的で最もよく䜿甚されたす。

pdftotext


この関数はコマンドラむンから簡単に呌び出され、次の圢匏になりたす。

$ pdftotext .pdf .txt


しかし、倉換結果は非垞に奇劙であるこずが刀明したした。

レゞストリから抜出する
お埗

オヌクションに続いお
CJSCサンクトペテルブルク
むンタヌナショナル
商品亀換

SET-VRSフォヌム

入札日1900幎1月1日
セクションSPbMTSB CJSCの石油補品セクション
メンバヌLLC
メンバヌコヌド000000000000
クラむアントの名前ずコヌドOJSC / 000000000000
ツヌルコヌド0000000001
ツヌルの説明Gasoline Premium Euro-95 type II class B、
数
お埗

時間
お埗

申蟌番号

賌入/取匕䟡栌数量ごず
セヌル¹
1トン
たくさん

01-01

02-02

01-03

S

01-05

5

02-01

02-02

02-03

S

02-05

1

0000000001の合蚈

などなど...

それだけでなく、出力はファむルごずに倉化したす-もちろん、この圢匏では、パヌサヌを䜜成しおテヌブルからデヌタをプルするこずはできたせんでした。

そのため、今床は独自の候補がもうすぐ登堎したす。Linux甚のAdobe Acrobat Readerです。

Acrobat Reader


この堎合、たず、コマンドラむンを詳しく調べるこずなく、グラフィカルモヌドで「ファむル-テキストずしお保存」の機胜をテストするこずにしたした。 埌で刀明したように、私は正しいこずをしたした-私のpdfずこのプログラムでの倉換の結果は楜芳䞻矩を刺激したせんでした

メンバヌID
セクション
ツヌルコヌド
ツヌルコヌド
000000000000
LLC
0000000001
0000000002
00,000,000.11 00,000.12
0,000,000.21 0,000.22
01-12
02-12
03-12
04-12
CJSCサンクトペテルブルク
むンタヌナショナル
商品亀換
レゞストリから抜出する
お埗
オヌクションに続いお
入札日1900幎1月1日
SET-VRSフォヌム
クラむアントの名前ずコヌドOJSC / 000000000000
メンバヌ
SPbMTSB CJSCのオむル補品セクション
ツヌルの説明Gasoline Premium Euro-95 type II class B、
コヌド
トレヌダヌ
時間
トランザクショントランザクション量
数
お埗
申蟌番号
0000000001の合蚈
ツヌルの説明冬のディヌれル燃料Z-0.2-35。
コヌド
トレヌダヌ
時間
トランザクショントランザクション量
数
お埗
申蟌番号
0000000002の合蚈

などなど...

このような結論を解析するために、私も本圓にしたくありたせんでした。

最埌に、最埌の候補はpdfeditでした 。

pdfedit


すべおのリポゞトリで、コマンドラむンからスクリプトを実行できるグラフィカルプログラムで衚されたす。 PDFをグラフィカル環境「ファむル-テキストずしお保存」から生成されたテキストに倉換する最初の開始であるAcrobat Readerず同様に、結果は非垞に満足しおいたす。

 
  CJSC「サンクトペテルブルクの登録SET-VRSフォヌムからの抜粋 
  囜際取匕 
  商品ず原料の亀換」入札の結果をフォロヌ 
                               入札日1900幎1月1日 
  セクションCJSC「SPbMTSB」のセクション「石油補品」 
  メンバヌLLC 
  メンバヌコヌド000000000000 
  クラむアントの名前ずコヌドOJSC / 000000000000 
  ツヌルコヌド0000000001 
  ツヌルの説明Gasoline Premium Euro-95 type II class B、 
    ルヌムタむムオヌダヌ番号 
                      賌入/取匕䟡栌数量ごず 
                                                    NDS Exchange名 
                                                                                  コヌド 
                                  CRCトランザクション量 
   取匕取匕セヌル¹ 
                        1トン 
                               ロット18カりンタヌパヌティコレクション 
                                                                               トレヌダヌ 
  01-01 01-02 01-03 S 01-05 5 01-07 01-08 01-09 01-10 PeSee 
                                                                             01-12 
  02-01 02-02 02-03 S 02-05 1 02-07 02-08 02-09 02-10 PbSE 
                                                                             02-12 
   0000000001 00,000,000.11 00,000.12の合蚈 
  ツヌルコヌド0000000002 
  ツヌルの説明冬のディヌれル燃料Z-0.2-35。 
    ルヌムタむムオヌダヌ番号 
                      賌入/取匕䟡栌数量ごず 
                                                    NDS Exchange名 
                                                                                  コヌド 
                                  CRCトランザクション量 
   取匕取匕セヌル¹ 
                        1トン 
                               ロット18カりンタヌパヌティコレクション 
                                                                               トレヌダヌ 
  03-01 03-02 03-03 S 03-05 1 03-07 03-08 03-09 03-10 PuSee 
                                                                             03-12 
  04-01 04-02 04-03 S 04-05 1 04-07 04-08 04-09 04-10 PgSee 
                                                                             04-12 
   0000000002の合蚈0.000.000.21 0.000.22 
  ブロヌカヌSPbMTSB電子文曞のコピヌ 
        ¹B-賌入、S-販売。  1/3 
 



結果は非垞に正しい結論でした-解析は簡単で快適です。 しかし、それはそこにありたせんでした、叙事詩を完了するための道は厄介でした。 暙準のpdfeditアセンブリのコマンドラむンから「テキストずしお保存」関数を呌び出すこずはできたせんでした。

 
  $ pdfedit -console 
  PDFedit 0.4.5 
  䜿甚法 
   pdfedit -console [関数名] [関数パラメヌタヌ耇数可] 
  最初のパラメヌタヌは、呌び出す関数の名前倧文字ず小文字を区別しないたたはその明確な郚分です。 
  残りのパラメヌタヌは、呌び出された関数に枡されたす。 
  利甚可胜な機胜 
   デリニアラむザ 
    説明入力ファむルの非線圢化 
    パラメヌタヌ[入力ファむル] [出力ファむル] 
   フラットナヌ 
    説明入力ファむルを統合最埌のリビゞョンを陀くすべおのリビゞョンを削陀 
    パラメヌタヌ[入力ファむル] [出力ファむル]  
 



コン゜ヌルヘルプの出力は、テキストぞの倉換ずは関係のない2぀のナヌティリティを提䟛したした。 wikiのドキュメントをさらに調査するず、既補の倉換スクリプトsavealltext.qsが䜜成されたしたが、問題は、グラフィカルメニュヌから実行する必芁があるこずです。 その結果、材料を詳现に調査する必芁がありたした。

pdfeditスクリプトAPIの説明
pdfeditスクリプト䜜成wiki
既補のスクリプトの䟋

この玠材の「喫煙」はすでに+暙準アセンブリで提瀺されおいるコン゜ヌルスクリプト/usr/share/pdfedit/delinearize.qsの段階的な分析-私は自分でsavealltext.qsを䜜成するこずになりたした。

 /** Print help for savealltext */ function savealltext_help() { print(tr("Usage:")); print("savealltext ["+tr("input file")+"] ["+tr("output file")+"]"); print(" "+tr("Input file must exist")); print(" "+tr("Output file must not exist")); exit(1); } function savealltext_fail(err) { print(tr("savealltext failed!")); print(err); exit(2); } function saveAsText_save(p,f) { document=loadPdf(p) qs=""; pages=document.getPageCount(); for (i=1;i<=pages;i++) { pg=document.getPage(i); text=pg.getText(); qs+=text; qs+="\n"; } saveFile(f,qs); } p=parameters(); if (p.length!=2) { savealltext_help("savealltext "+tr("is expecting two parameters")); } inFile=p[0]; outFile=p[1]; if (!exists(inFile)) savealltext_fail(tr("Input file '%1' does not exist").arg(inFile)); if (exists(outFile)) savealltext_fail(tr("Output file '%1' already exist").arg(outFile)); if (inFile==outFile) savealltext_fail(tr("Input and output files must be different")); if (saveAsText_save(inFile,outFile)) { } else { print(tr("savealltext")+" :"+inFile+" -> "+outFile); } 
/** Print help for savealltext */ function savealltext_help() { print(tr("Usage:")); print("savealltext ["+tr("input file")+"] ["+tr("output file")+"]"); print(" "+tr("Input file must exist")); print(" "+tr("Output file must not exist")); exit(1); } function savealltext_fail(err) { print(tr("savealltext failed!")); print(err); exit(2); } function saveAsText_save(p,f) { document=loadPdf(p) qs=""; pages=document.getPageCount(); for (i=1;i<=pages;i++) { pg=document.getPage(i); text=pg.getText(); qs+=text; qs+="\n"; } saveFile(f,qs); } p=parameters(); if (p.length!=2) { savealltext_help("savealltext "+tr("is expecting two parameters")); } inFile=p[0]; outFile=p[1]; if (!exists(inFile)) savealltext_fail(tr("Input file '%1' does not exist").arg(inFile)); if (exists(outFile)) savealltext_fail(tr("Output file '%1' already exist").arg(outFile)); if (inFile==outFile) savealltext_fail(tr("Input and output files must be different")); if (saveAsText_save(inFile,outFile)) { } else { print(tr("savealltext")+" :"+inFile+" -> "+outFile); }

/ usr / share / pdfedit /ディレクトリに配眮されるず、スクリプトはコマンドラむンから呌び出され、必芁な倉換を実行したす。

 
  $ pdfedit -console 
  PDFedit 0.4.5-20111014140242 
  䜿甚法 
   pdfedit -console [関数名] [関数パラメヌタヌ耇数可] 
  最初のパラメヌタヌは、呌び出す関数の名前倧文字ず小文字を区別しないたたはその明確な郚分です。 
  残りのパラメヌタヌは、呌び出された関数に枡されたす。 
  利甚可胜な機胜 
   デリニアラむザ 
    説明入力ファむルの非線圢化 
    パラメヌタヌ[入力ファむル] [出力ファむル] 
   フラットナヌ 
    説明入力ファむルを統合最埌のリビゞョンを陀くすべおのリビゞョンを削陀 
    パラメヌタヌ[入力ファむル] [出力ファむル] 
   savealltext 
    説明savealltext入力ファむル 
    パラメヌタヌ[入力ファむル] [出力ファむル] 
 



$pdfedit -console savealltext .pdf .txt

すべおがうたくいくように芋えたしたが、萜ずし穎は浮かび䞊がりたしたコン゜ヌルモヌドで、pdfeditが612x792ピクセルのデフォルト領域からテキストを遞択するこずが刀明したした-これは、72 dpiの解像床でA4暪向きシヌトに察応したす。 パッチrotate_text_fix.patchからの察応する呜什のコヌド内に存圚するにもかかわらず、プログラムはスキャン領域を回転させたくありたせんでした 。
このトリッキヌな「デフォルト゚リア」の定矩を怜玢するず、プロゞェクト゜ヌスコヌド 、ファむルsrc / kernel / displayparams.hに移動したした。結局のずころ、どこに配眮するかがわかりたした。

static const int DEFAULT_PAGE_RX = 612; /**< Default A4 width on a device with 72 horizontal dpi. */
static const int DEFAULT_PAGE_RY = 792; /**< Default A4 height on a device with 72 vertical dpi. */

䞡方の倀を1584ポむント同じ解像床のwhatmanの半分に盞圓に眮き換え、プロゞェクトを再倉換したした。

これに぀いおは、苊痛は終わったず蚀うこずができたす-PDFは、A4thランドスケヌプアルバムランドスケヌプのすべおで、タヌミナルから凊理されたした。
圌の苊痛の結果に基づいお、圌はArchLinuxのsavealltextでpdfeditパッケヌゞを構築するルヌルを䜜成し、それをAURに入れたした
pdfeditリリヌス
csvからのpdfeditバヌゞョン

PS


おずぎ話はすぐに圱響を及がしたすが、すぐには完了したせん。コン゜ヌルモヌドであっおも、システムでqt3が必芁なpdfeditの実行は本圓に奜きではありたせんでした。

$ pdfedit -console
pdfedit共有ラむブラリのロヌド䞭に゚ラヌが発生したしたlibqt-mt.so.3共有オブゞェクトファむルを開けたせんそのようなファむルたたはディレクトリはありたせん

これにより、゜ヌスからビルドするずきにプログラムの構成キヌが考慮され、次のレシピが芋぀かりたした。

configure --disable-gui --enable-pdfedit-core-dev --enable-tools

その結果、グラフィックpdfeditバむナリはたったく構築されたせんが、savealltext.qsスクリプトず同じアルゎリズムを䜿甚しお、pdf_to_text-必芁な倉換を実行する有甚なナヌティリティ党䜓が䜜成されたす。

$pdf_to_txt -file .pdf >.txt

このようなプロゞェクトアセンブリの結果は、ArchLinuxのPKGBUILDに倉換され、 AURに投皿されたした。

upd1


ご盞談ありがずうございたした 議論のおかげで、pdfをテキストに倉換するさらに興味深い方法がいく぀か明らかになりたした。
zelibobaはpdftotextに-layoutオプションを適甚するこずを提案したした
$ pdftotext -layout .pdf .txt

誇匵するこずなく、蚘事のプロゞェクトファむルはpdfeditよりもこの方法をより良く倉換するず蚀うこずができたす。

 
  CJSC「サンクトペテルブルクの登録SET-VRSフォヌムからの抜粋 
  囜際取匕 
  商品ず原料の亀換」入札の結果をフォロヌ 

                                                                          入札日1900幎1月1日 

  セクションCJSC「SPbMTSB」のセクション「石油補品」 
  メンバヌLLC 
  メンバヌコヌド000000000000 
  クラむアントの名前ずコヌドOJSC / 000000000000 

  ツヌルコヌド0000000001 
  ツヌルの説明Gasoline Premium Euro-95 type II class B、 

   番号時間泚文番号賌入/取匕䟡栌付加䟡倀皎の額取匕所名コヌド 
                                                                                   CRCトランザクション量 
   取匕取匕販売¹1トンのロット18トレヌダヌのカりンタヌパヌティのコレクション 

  01-01 01-02 01-03 S 01-05 5 01-07 01-08 01-09 01-10 PeSee 01-12 
  02-01 02-02 02-03 S 02-05 1 02-07 02-08 02-09 02-10 PbSee 02-12 

   0000000001 00,000,000.11 00,000.12の合蚈 
 



䞀方、すべおのPDFでこのルヌルが機胜するわけではありたせん。
「今日、さたざたなpdfファむルを詊したしたが、pdfeditずpdftotextの間にはただ絶察的なチャンピオンが存圚しないこずがわかりたした。
Pdftotext-䞀連の氎平方向に现長いテヌブルず単䞀列のマガゞンをより適切に倉換したした。
Pdfedit-耇数列のログ䟋linuxformatず垂盎方向のテヌブルでよりよく機胜したした。
どちらのプログラムも同じ結果を瀺したした䟋Zeinghaus誌。」

kornerzは、inkscapeを䜿甚しおpdfをsvgに倉換するこずを提案したした-以前はpdfファむルをシヌトに分割しおいたしたpdftkを䜿甚するオプションずしお

$pdftk file.pdf burst

$inkscape -z -f pg_0001.pdf -l output_page1.svg

Source: https://habr.com/ru/post/J130601/


All Articles