誰かがiTextSharpでこれを行ったのではないかと思いますが、複数のPDFファイルを1つに結合したいのですが、改ページは残しておきます。たとえば、それぞれ3行のテキストを含む4つのPDFファイルを作成したいので、結果のファイルに1ページに12行すべてを含める必要があります。これは可能ですか?
OPもこの質問に[iText]のタグを付けており、私は.NetよりもJavaに慣れているので、ここでiText / Javaの回答を示します。iTextSharp / C#に簡単に翻訳できるはずです。
複数のPDFファイルを1つに結合したいのですが、改ページは残しておきます。たとえば、それぞれ3行のテキストを含む4つのPDFファイルを作成したいので、結果のファイルに1ページに12行すべてを含める必要があります。
その例に示されているPDFファイルの場合、次の単純なユーティリティクラスを使用できます。
public class PdfDenseMergeTool
{
public PdfDenseMergeTool(Rectangle size, float top, float bottom, float gap)
{
this.pageSize = size;
this.topMargin = top;
this.bottomMargin = bottom;
this.gap = gap;
}
public void merge(OutputStream outputStream, Iterable<PdfReader> inputs) throws DocumentException, IOException
{
try
{
openDocument(outputStream);
for (PdfReader reader: inputs)
{
merge(reader);
}
}
finally
{
closeDocument();
}
}
void openDocument(OutputStream outputStream) throws DocumentException
{
final Document document = new Document(pageSize, 36, 36, topMargin, bottomMargin);
final PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
this.document = document;
this.writer = writer;
newPage();
}
void closeDocument()
{
try
{
document.close();
}
finally
{
this.document = null;
this.writer = null;
this.yPosition = 0;
}
}
void newPage()
{
document.newPage();
yPosition = pageSize.getTop(topMargin);
}
void merge(PdfReader reader) throws IOException
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
for (int page = 1; page <= reader.getNumberOfPages(); page++)
{
merge(reader, parser, page);
}
}
void merge(PdfReader reader, PdfReaderContentParser parser, int page) throws IOException
{
TextMarginFinder finder = parser.processContent(page, new TextMarginFinder());
Rectangle pageSizeToImport = reader.getPageSize(page);
float heightToImport = finder.getHeight();
float maxHeight = pageSize.getHeight() - topMargin - bottomMargin;
if (heightToImport > maxHeight)
{
throw new IllegalArgumentException(String.format("Page %s content too large; height: %s, limit: %s.", page, heightToImport, maxHeight));
}
if (heightToImport > yPosition - pageSize.getBottom(bottomMargin))
{
newPage();
}
else if (!writer.isPageEmpty())
{
heightToImport += gap;
}
yPosition -= heightToImport;
PdfImportedPage importedPage = writer.getImportedPage(reader, page);
writer.getDirectContent().addTemplate(importedPage, 0, yPosition - (finder.getLly() - pageSizeToImport.getBottom()));
}
Document document = null;
PdfWriter writer = null;
float yPosition = 0;
final Rectangle pageSize;
final float topMargin;
final float bottomMargin;
final float gap;
}
PdfReader
インスタンスのリストがある場合はinputs
、次のようにそれらをOutputStream output
:にマージできます。
PdfDenseMergeTool tool = new PdfDenseMergeTool(PageSize.A4, 18, 18, 5);
tool.merge(output, inputs);
これにより、A4ページサイズ、それぞれ18/72 "の上下の余白、および5/72"の異なるPDFページのコンテンツ間のギャップを使用してマージされたドキュメントが作成されます。
iText TextMarginFinder
(PdfDenseMergeTool
上記で使用)はテキストのみを考慮します。他のコンテンツタイプも考慮する必要がある場合は、このクラスをいくらか拡張する必要があります。
各PDFには、おそらく表や画像など、数行しかありませんが、最終結果を1ページにしたいと思います。
テーブルにテキストコンテンツの上または下に達する装飾(線や色付きの背景など)が含まれている場合は、より大きなギャップ値を使用する必要があります。残念ながら、によって使用される解析フレームワークは、TextMarginFinder
ベクターグラフィックスコマンドをファインダーに転送しません。
画像がビットマップ画像の場合は、画像領域も考慮に入れるメソッドをTextMarginFinder
実装して拡張する必要がrenderImage
あります。
また、一部のPDFにはフィールドが含まれている場合があるため、結果の結合されたPDFにもそれらのフィールドを保持したいと思います。
AcroFormフィールドも考慮する必要がある場合は、次のことを行う必要があります。
TextMarginFinder
、ウィジェット注釈の視覚化長方形も含めます。PdfDenseMergeTool.merge(PdfReader, PdfReaderContentParser, int)
メソッドを拡張して、これらのウィジェットの注釈もコピーします。私は上に書いた
残念ながら、によって使用される解析フレームワークは、
TextMarginFinder
ベクターグラフィックスコマンドをファインダーに転送しません。
一方(バージョン5.5.6)、その解析フレームワークは、ベクターグラフィックスコマンドも転送するように拡張されました。
ラインを交換する場合
TextMarginFinder finder = parser.processContent(page, new TextMarginFinder());
沿って
MarginFinder finder = parser.processContent(page, new MarginFinder());
この回答の下部に示されているMarginFinder
クラスを使用すると、テキストだけでなく、すべてのコンテンツが考慮されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加