iTextを使ってドキュメント内に行がどこにあるのか、どのように見つけることができますか?iTextを使って行の位置を取得する
たとえば、PDFドキュメントにテーブルがあり、その内容を読みたいとします。私は正確に細胞がどこにあるのかを知りたい。それを行うために、私は線の交差点を見つけるかもしれないと思った。
iTextを使ってドキュメント内に行がどこにあるのか、どのように見つけることができますか?iTextを使って行の位置を取得する
たとえば、PDFドキュメントにテーブルがあり、その内容を読みたいとします。私は正確に細胞がどこにあるのかを知りたい。それを行うために、私は線の交差点を見つけるかもしれないと思った。
iTextを使用する唯一のオプションは、PDFトークンを手動で解析することだと思います。それをする前に私はhave a copy of the PDF spec handyでしょう。
(私はiTextSharpを使用しますが、いくつかの大文字小文字の違いとプロパティ宣言以外に、彼らは同じほぼ100%ですので、私は、.NET男だ。)
あなたはPRTokeniser
を使用して、個々のトークンを取得することができますあなたのPdfReader
のgetPageContent(pageNum)
を呼び出すことからバイトを送るオブジェクト。 PRTokeniser
て
//Get bytes for page 1
byte[] pageBytes = reader.getPageContent(1);
//Get the tokens for page 1
PRTokeniser tokeniser = new PRTokeniser(pageBytes);
それからちょうどループ:
PRTokeniser.TokType tokenType;
string tokenValue;
while (tokeniser.nextToken()) {
tokenType = tokeniser.tokenType;
tokenValue = tokeniser.stringValue;
//...check tokenValue, do something with it
}
限りtokenValue
、あなたはおそらく四角形とラインのre
とl
値を探したいと思います。あなたがre
を見るなら、あなたは以前 4値では、あなたが、その後l
以前 2の値を見れば見てみたいです。これはまた、後で振り返ることができるように、各tokenValue
を配列に格納する必要があることを意味します。
PDFの作成に使用した内容に応じて、興味深い結果が得られる場合があります。たとえば、Microsoft Wordで4つのセルテーブルを作成し、PDFとして保存しました。何らかの理由で10個の四角形が2つあり、重複していますが、一般的な考え方は変わりません。
以下は、iTextSharp 5.1.1.0をターゲットとするC#コードです。あなたはそれをJavaとiTextに非常に簡単に変換できるはずです。一般的なリスト(List<string>
)からJava同等のもの(おそらくArrayList
)に調整する必要がある.Net固有のコードを持つ1行に留意しました。いくつかのケーシングを調整する必要があります.Netはを使用するのに対し、.NetはObject.Method()
を使用します。最後に.Netは取得と設定なしでプロパティにアクセスするため、Object.Property
はJavaのObject.getProperty
とObject.setProperty
と比較してゲッターとセッターの両方です。
これはあなたが少なくとも始めることを望みます。
//Source file to read from
string sourceFile = "c:\\Hello.pdf";
//Bind a reader to our PDF
PdfReader reader = new PdfReader(sourceFile);
//Create our buffer for previous token values. For Java users, List<string> is a generic list, probably most similar to an ArrayList
List<string> buf = new List<string>();
//Get the raw bytes for the page
byte[] pageBytes = reader.GetPageContent(1);
//Get the raw tokens from the bytes
PRTokeniser tokeniser = new PRTokeniser(pageBytes);
//Create some variables to set later
PRTokeniser.TokType tokenType;
string tokenValue;
//Loop through each token
while (tokeniser.NextToken()) {
//Get the types and value
tokenType = tokeniser.TokenType;
tokenValue = tokeniser.StringValue;
//If the type is a numeric type
if (tokenType == PRTokeniser.TokType.NUMBER) {
//Store it in our buffer for later user
buf.Add(tokenValue);
//Otherwise we only care about raw commands which are categorized as "OTHER"
} else if (tokenType == PRTokeniser.TokType.OTHER) {
//Look for a rectangle token
if (tokenValue == "re") {
//Sanity check, make sure we have enough items in the buffer
if (buf.Count < 4) throw new Exception("Not enough elements in buffer for a rectangle");
//Read and convert the values
float x = float.Parse(buf[buf.Count - 4]);
float y = float.Parse(buf[buf.Count - 3]);
float w = float.Parse(buf[buf.Count - 2]);
float h = float.Parse(buf[buf.Count - 1]);
//..do something with them here
}
}
}
答えのPDF Specへのリンクは有効ではなくなりました。このURLを試すことができます。 https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf – user1567291