カテゴリー別アーカイブ: プログラミング

iTextSharpメモ2

PDFの内部構造を調べていくと、深みにはまって窒息しそうになりつつも、なんとか日本語読み取りまで辿り着いたメモ。

そもそもの困難の元は、PDF内部において文章部分が文字コードそのもので書かれているのではなく、CIDとかいうフォントコード(?)に変換されてること。文字コードからCIDへの変換はCMAPというファイルに記述されているらしく、確かにAcrobatのサブフォルダにCMapというフォルダあってファイルがずらり。フォントコードが直接書いてあるから表示には楽なんだろうけど、内容を読み取るにはCIDから文字コードに戻さないといけない、と。CMAPがあるんだから簡単かと思ったものの、ほとんどのCMAPは「文字コード→CID」で記述されていて逆変換はあまり考慮されていない様子。その逆変換を自前でなんてムリムリ…、と怠惰精神でさらに調べていくと、iTextSharpにはiTextAsianというパッケージがあって(allには含まれていなくてextrasにある)、ver2.1からはCMAPも内包しているようなのでこれを使えば何とかなるんでは?、ということで調べ/試しまくって何とかなった! 以下、手順はVisualStudio2013とiTextAsian-all-2.1.zipを使ってのお話。

必要な手順は
1.iTextAsian自体の再構築
オリジナルのiTextAsian.dllは何が悪いのか、リソースに追加しても動作しないので新しく作り直します。iTextAsian-src-2.1.zipを解凍して出てくるiTextAsian.csprojをVS2013で読み込むと自動でプロジェクト変換してくれるので、そのままビルドすればOK。
2.AddToResourceSearchでiTextAsian.dllをリソースに追加
新しく作ったdll、上ではあっさり「リソースに追加」と書きましたが、単純にソリューションの参照に追加しても動作しません。参照に追加した上で、ソースコードからもAddToResourceSearchメソッドで追加する必要があります。なおこのAddToResourceSearchというメソッド、本家iTextではiTextSharp.text.pdf.BaseFontクラスにありますが、iTextSharpではぜんぜん違うところ、iTextSharp.text.io.StreamUtilにあります。読み込みは1回やればいいので、フォームのコンストラクタに
  iTextSharp.text.io.StreamUtil.AddToResourceSearch("iTextAsian.dll");
の1行を書き加えればOK。

こうして作ったアプリで前回読み込めなかったこのファイルを読み込むと

pdftextext03

 

となって日本語取り出し成功です!。

iTextSharpメモ1

C#(iTextSharp)で日本語PDFを読み込もうとしているのですが、なかなかハードルが高くて苦戦中。読めるファイルもあれば読めないファイルもあり、とりあえず今のところまでのメモ。とりあえず以下のようなコードで動作確認してみます。

前略
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
中略
var pdf = new PdfReader(filename);
var raw = pdf.GetPageContent(1);
var rawText = ASCIIEncoding.ASCII.GetString(raw);
var extText = PdfTextExtractor.GetTextFromPage(pdf, 1, new SimpleTextExtractionStrategy());
extText = extText.Replace("\r", "\\r").Replace("\n","\\n" + Environment.NewLine);
後略

みたいなコードで、左側にrowText、右側にextTextを表示するようなフォームを作って適当なpdfを読み込んでみます。例えば経産省にあるpdfを開いてみると、それなりに日本語抽出できてます。
iTextSharp習作01
が、同じ官公庁のpdfでもこっちだと全角部分は全滅、0325001、16、03、19という半角数字だけしか読めてません。CJKフォント周りがどうにも不安定。

pdftextext02

Access覚え書き(1),フォームのSQL文本体

Accessのフォームに表示されてるデータって、実際はどこから引っ張ってこられた物なのかを知りたくて四苦八苦した記録。

出来てみるとあっけないのだけど、変なところ探しまくって憤死しそうになってました。結局のところ正解は...

「フォームをデザインビューで開いて、何もないところで右クリックしてプロパティ→レコードソースがそのフォームで使われてるSELECT文。」

会社で使われてる購買管理システム(MS Access)、テーブルはめちゃくちゃに細分化されてて訳分からんのですが、検索フォームでは確かに欲しい情報が一覧で出るのです。こいつは一体どうやってんだ、そもそもこの値はどのテーブルにあるんだ、という好奇心で30分近くつぶした成果が上記の作業だった訳です。全く僕にしか役に立たない記録だけど、また忘れそうなのでメモ。