1

ページを介してPDFファイルを解析し、それぞれを個別にbyte[]. itext ライブラリを使用します。

次のコードを含む 1 ページで構成されるファイルをダウンロードします。

   public Document addPageInTheDocument(String namePage, MultipartFile pdfData, Long documentId) throws IOException {
      notNull(namePage, INVALID_PARAMETRE);
      notNull(pdfData, INVALID_PARAMETRE);
      notNull(documentId, INVALID_PARAMETRE);
      byte[] in = pdfData.getBytes(); // size file 88747
      Page page = new Page(namePage);
      Document document = new Document();
      document.setId(documentId);
      PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfData.getBytes()));
      PdfDocument pdfDocument = new PdfDocument(reader);
      if (pdfDocument.getNumberOfPages() != 1) {
          throw new IllegalArgumentException();
      }
      byte[] transform = pdfDocument.getPage(1).getContentBytes(); // 1907 size page
      page.setPageData(pdfDocument.getPage(1).getContentBytes());
      return addPageInTheDocument(document, page);
  }

このコードでファイルを復元しようとしています:

ByteBuffer byteContent = new ByteBuffer() ;
    for (Map.Entry<String, Page> page : pages.entrySet()) {
       byteContent.append(page.getValue().getPageData());
    }
    PdfWriter writer = new PdfWriter(new FileOutputStream(book.getName() + modification + FORMAT));
    byte[] df = byteContent.toByteArray();
    PdfReader reader = new PdfReader(new ByteArrayInputStream(byteContent.toByteArray()));
    com.itextpdf.layout.Document itextDocument = new com.itextpdf.layout.Document(new PdfDocument(reader, writer));
    itextDocument.close();

なぜこのようなサイズの違いがあるのでしょうか? そして、なぜファイルとページ、そして両方がbyte[]ファイルを作成するのでしょうか?

4

1 に答える 1

0

サイズの質問から始めましょう。

byte[] in = pdfData.getBytes(); // size file 88747
...
byte[] transform = pdfDocument.getPage(1).getContentBytes(); // 1907 size page

...

なぜこのようなサイズの違いがあるのでしょうか?

あなたPdfPage.getContentBytes()が期待するものを返さないからです。

指定されたページのコンテンツの完全な表現を返すことを期待しているようで、そのメソッドの Javadoc はそれを意味するように解釈される可能性があります ( 「ページ コンテンツ全体のデコードされたバイトを取得します。」 )。

これはそうではありません。ページのコンテンツ ストリームPdfPage.getContentBytes()のコンテンツを返します。これらのコンテンツ ストリームには、ページを構築する一連のコマンドが含まれています。ただし、これらのコマンドは、コンテンツ ストリームの外部のデータを参照するパラメータを取ります。たとえば、次のようになります。

  • テキストが PDF ページに描画される場合、コンテンツ ストリームにはフォントを選択する操作が含まれますが、フォントを記述するデータが含まれます。埋め込みフォントの場合、フォント プログラム自体はコンテンツ ストリームの外にあります。
  • ビットマップ画像が描画されるとき、コンテンツ ストリームには通常、コンテンツ ストリームの外部の画像データを参照する操作が含まれます。
  • 基本的に任意のページから呼び出すことができる独立したコンテンツ ストリームである、いわゆる xobjects を参照する操作があります。これらの xobject は、ページ コンテンツ ストリームにも含まれていません。

さらに、個別の構造に格納された独自のコンテンツ ストリームを持つ注釈 (フォーム フィールドなど) があります。また、多くのページ プロパティも外部にあります。

したがって、を使用してページ定義のごく一部しか取得できないため、このようなサイズの違いがありgetContentBytesます。


次に、「ファイルを復元する」コードを見てみましょう。

上記の当然の結果として、コードがいくつかのコンテンツ ストリームを連結しているだけで、これらのストリームが参照する外部リソースを提供していないことは明らかです。

しかし、それとは別に、コードは PDF ページの性質に関する誤解も指摘しています。それらは、必要に応じて分割して再度連結できる単なる blob ではありません。これらは、PDF ファイル全体に広がる PDF オブジェクトのコレクションです。異なるページでオブジェクトの一部を共有できます (例: 頻繁に使用される画像のフォント)。


代わりにできることは...

単一ページの表現として、その単一ページが参照するデータを含む PDF を使用する必要があります。iText の例Burst.javaは、その方法を示しています。

これらの単一ページの PDF を再度結合するには、 iText を使用できますPdfMergerPdfWriter.setSmartMode(true)結果でリソースが重複しないように、必ずスマート モード ( ) を設定してください。

于 2016-08-02T07:15:54.143 に答える