2016-10-05 2 views
0

iTextで生成されたPDFをサーバー側からクライアント側に戻して、ユーザーが保存できるようにしようとしています。私は、次のいHow to convert iTextPDF Document to Byte Array(AceFunk)iText PDFドキュメントをクライアント側に返す方法

private static ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

    public static byte[] main(java.util.List<Transcript> listymAwards, String scoutName, String groupName) { 
    Document document = new Document(PageSize.A4, 0f, 0f, 0f, 0f); 

try { 

    //PdfWriter.getInstance(document, new FileOutputStream(FILE)); 
    PdfWriter.getInstance(document, byteArrayOutputStream); // Do this BEFORE document.open() 

    document.open(); 
    addMetaData(document); 
    addImages(document); 
    addTitlePage(document, scoutName); 

    //Add the table of achievements 
    if (listymAwards == null || listymAwards.isEmpty()) { 
     //Nothing to do. 
     //System.out.println("Scout not found."); 
    }else{ 

     Paragraph preface = new Paragraph(); 

     PdfPTable table = new PdfPTable(3); 
     table.setWidths(new int[]{1, 3, 1}); 
     table.setHeaderRows(1); 

     PdfPCell c1 = new PdfPCell(new Phrase("Section")); 
     c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
     table.addCell(c1); 

     c1 = new PdfPCell(new Phrase("Award")); 
     c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
     table.addCell(c1); 

     c1 = new PdfPCell(new Phrase("Date")); 
     c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
     table.addCell(c1); 
     table.setHeaderRows(1); 

     String storedName = null; 
     int noRows = 0; 
     String firstTable = "Yes"; 
     DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd"); 
     DateFormat df2 = new SimpleDateFormat("dd-MM-yyyy"); 
     // We add three empty lines 
     addEmptyLine(preface, 1); 
     addEmptyLine(preface, 1); 
     addEmptyLine(preface, 1); 

     for (final Transcript scoutNamesDescription : listymAwards) { 
      if (firstTable.equals("Yes") && noRows > 30){ // Change this to number of rows required 
       noRows = 0; 
       firstTable = "No"; 
       document.add(table); 
       document.newPage(); 
       table.flushContent(); 
      }else{ 
       if (firstTable.equals("No") && noRows > 50){ // Change this to number of rows required 
        // We add three empty lines if not the first table 
        document.add(preface); 
       } 
      } 

      noRows++; 

      if (scoutNamesDescription.getSection().equals(storedName)){ 
       table.addCell(" "); 
      }else{ 
       storedName = scoutNamesDescription.getSection(); 
       table.addCell(scoutNamesDescription.getSection()); 
      } 
      table.addCell(scoutNamesDescription.getAwardName()); 

      Date awardedDate = df1.parse(scoutNamesDescription.getAwardedDate()); 
      String awardedString = df2.format(awardedDate); 
      table.addCell(awardedString); 
     } 
     //Print the remaining rows. 
     // We add three empty lines if not the first table 
     if (firstTable.equals("No")){ 
      document.add(preface); 
     }else{ 
      firstTable = "No"; 
     } 
     document.add(table); 
    } 

    //Add signature 
    addSignaturePage(document, groupName); 

    document.close(); 


} catch (Exception e) { 
    e.printStackTrace(); 
} 

byte[] pdfBytes = byteArrayOutputStream.toByteArray(); 
return pdfBytes; 

}これは、サーバー側に戻される

byte[] pdfBytes = ScoutTranscript.main(listymAwards, scoutName, groupName); 
    System.out.println("Point 3"); 

    return pdfBytes; 

、クライアント側に戻される。

Window.open("data:application/pdf;base64,"+result,"_parent", "location=no"); 

エラーメッセージが表示される場所:

This site can’t be reached 

The webpage at data:application/pdf;base64,[[email protected] might be temporarily down or it may have moved permanently to a new web address. 
+0

すぐに、またはしばらくしてこのメ​​ッセージが表示されますか? –

+0

メッセージはかなり速く表示されます。 – Glyn

+0

あなたはpdfを提供するためにサーブレットを使用していませんか?あなたは(RequestFactory/GWT-RPC)を使ってpdfの内容を転送していますか?私は、HttpServletを使用することをお勧めします。次に、バイト配列をServletOutputStreamに書き込んで、http応答の正しいヘッダーを設定するだけです。 – Akkusativobjekt

答えて

2

エラー#1:

はのは、どのような方法でiTextのを必要としない小規模なテストから始めましょう。試してみてください:

byte[] test = "Test".getBytes(); 
System.out.println("Test " + test); 

出力には何が書き込まれますか?私の場合、それはです:

Test [[email protected] 

[私はStringに配列を変換しようとしていますことを示します。 Bは、配列にバイトが含まれていることを示します。 @はIDとタイプを区切ります。続く文字は16進形式のID(ハッシュコード)です。 "data:application/pdf;base64,[[email protected]"のようなもので

Window.open("data:application/pdf;base64,"+result,"_parent", "location=no"); 

その後"data:application/pdf;base64,"+result結果:resultはタイプbyte[]のものであり、この行を持っている場合Java: Syntax and meaning behind "[[email protected]"? Binary/Address?

を参照してください。それは意味をなさないですね。

さて、これを試してみてください。

byte[] test = "Test".getBytes(); 
System.out.println("Test " + new String(test)); 

出力は次のようになります。それはStringだったかのようにあなたがbyte[]を使用していた

Test Test 

。これがあなたの最初のエラーです。

これは、Javaの開発者が作成するエラーではないため、私は何か厄介なことを言うつもりでした。しかし、私はちょうどあなたのバイオを読んだだけで、あなたはJavaで新しく、(おそらく)Javaでコードする方法を教えているように(私は20年前と同じように)、私は自分自身を検閲しました;-)

エラー#2:バイト単位:あなたは2番目のエラーを作っているので、

あなたはそれを行うことはできません
Window.open("data:application/pdf;base64,"+ new String(result),"_parent", "location=no"); 

次の方法で、あなたのコードを置き換えることで、あなたの問題を解決することはできませんresultバイナリファイルを表し、ブラウザのJavaScriptは予期していますBase64でエンコードされたファイル。バイナリをテキストに変換するためにBase64エンコーディングが使用され、その逆もあります。 What is base 64 encoding used for?

バイナリPDFファイルをBase64でエンコードされた文字列としてブラウザに送信するには、Base64でエンコードする必要があります。これは、このクラスで行うことができます。http://itextsupport.com/apidocs/itext5/latest/com/itextpdf/text/pdf/codec/Base64.html

例えば:

Window.open("data:application/pdf;base64,"+ Base64.encodeBytes(result),"_parent", "location=no"); 

これは、すでにいくつかのブラウザのために働く必要があり、すべてではないため。 Window.open()をどこで使用しているのかわからず、なぜBase64を使用したいのですか。あなたはそれについて詳述したいかもしれません。私の意見では、それは悪い考えです。それが行われる必要がありますどのように

通常は、アプリケーションサーバで実行さServletを書き込みます。そのサーブレットは、URLを使用してブラウザからアクセスできます。 生成されたファイルをサーバに保存する必要はありません。他の回答に示唆されているとおりです(私はその回答を間違っていたため、投票しませんでした)。 ByteArrayOutputStreamを作成してbyte[]を取得する方法は正しいですが、これらのバイトをHttpServletResponseオブジェクトに提供する必要があります。

詳しくは、How can I serve a PDF to a browser without storing a file on the server side?を参照してください。 Window.open()

について

は、あなたが新しいウィンドウでWebページを開くには、クライアント側でWindow.open()を使用することができます。例えば:

window.open("http://www.itextpdf.com"); 

あなたはこのスニペットが含まれていたページを提供することができますが、あなたのケースでは、あなたのサーブレット用に定義されたURLにhttp://www.itextpdf.comを交換する必要があります。

あなたが発見したことがあり、ここであなたの「ソリューション」:Opening PDF String in new window with javascript

しかし、あなたがコメントを読めば、あなたはこのアプローチはいくつかのブラウザとの組み合わせで問題があることがわかります。

+0

これは非常にあなたに非常に寛大なブルーノありがとうございます。私は注意深くこれとリンクを読んで、私のコードを変更しました。私は今、私は3つのパラメータを持つように呼び出す方法を知る必要があります最初の文字列です。私のポストを見てください。 – Glyn

+0

新しい質問を投稿するために回答を使用しました。これはStack Overflowのルールに反します。あなたは新しい質問を投稿するべきです。 'param1'をHTTPリクエストで配列としてポストしたいのですが、間違った方法でやっているようです。私は自分の電話から回答しています(これはikを検索するのをより困難にします)が、誰かがすでにこれに答えていると確信しています。私は自分のコンピュータで過ごす時間があればその答えへのリンクを掲示します。 –

+1

それを見つけました:http://stackoverflow.com/questions/3061273/send-an-array-with-an-http-get(コードを変更する必要があります; 'String.format()'は十分である。) –

関連する問題