Java 如何将iText PDF文档返回到客户端
我试图将一个iText生成的PDF从服务器端返回到客户端,以便用户能够存储它。我在跟踪(AceFunk) 然后返回到客户端:Java 如何将iText PDF文档返回到客户端,java,gwt,itext,Java,Gwt,Itext,我试图将一个iText生成的PDF从服务器端返回到客户端,以便用户能够存储它。我在跟踪(AceFunk) 然后返回到客户端: Window.open("data:application/pdf;base64,"+result,"_parent", "location=no"); 我从中得到错误消息: This site can’t be reached The webpage at data:application/pdf;base64,[B@154 might be temporarily
Window.open("data:application/pdf;base64,"+result,"_parent", "location=no");
我从中得到错误消息:
This site can’t be reached
The webpage at data:application/pdf;base64,[B@154 might be temporarily down or it may have moved permanently to a new web address.
错误#1:
让我们从一个小测试开始,它不以任何方式涉及iText。试试这个:
byte[] test = "Test".getBytes();
System.out.println("Test " + test);
输出中写入了什么?就我而言,它是:
Test [B@3da3da69
[
表示我正在尝试将数组转换为字符串;B
表示数组包含字节;@
将类型与ID分开;后面的字符是十六进制格式的ID(哈希码)。请参阅
如果result
的类型为byte[]
且您有以下行:
Window.open("data:application/pdf;base64,"+result,"_parent", "location=no");
然后,+result
产生类似于“data:application/pdf;base64[B@154“
。这没有任何意义,是吗
现在试试这个:
byte[] test = "Test".getBytes();
System.out.println("Test " + new String(test));
输出为:
Test Test
您使用的是字节[]
,就好像它是字符串一样。这是您的第一个错误
我本想说一些令人讨厌的话,因为这不是Java开发人员会犯的错误。然而,我刚刚读了你的简历,我发现你是Java新手,你(可能)正在自学如何用Java编写代码(就像我20年前做的那样),所以我审查了自己;-)
错误#2:
您无法通过以下方式替换代码来解决问题:
Window.open("data:application/pdf;base64,"+ new String(result),"_parent", "location=no");
您不能这样做,因为您正在犯第二个错误:result
中的字节表示一个二进制文件,而浏览器中的JavaScript需要一个Base64编码的文件。Base64编码用于将二进制转换为文本,反之亦然。请参阅
如果要将二进制PDF文件作为Base64编码字符串发送到浏览器,则必须对字节进行Base64编码。这可以通过此类完成:
例如:
Window.open("data:application/pdf;base64,"+ Base64.encodeBytes(result),"_parent", "location=no");
window.open("http://www.itextpdf.com");
这应该已经适用于某些浏览器,但不是所有浏览器。我不知道您在哪里使用Window.open()
,也不知道为什么要使用Base64。您可能需要详细说明一下。在我看来,这是一个坏主意
应该如何做:
通常,您将编写一个在应用程序服务器中运行的Servlet
。可以使用URL从浏览器访问该Servlet。您不需要像另一个答案中所建议的那样将生成的文件保存在服务器上(我否决了该答案,因为它没有帮助,而且完全错误)。您创建ByteArrayOutputStream
然后获取字节[]
的方法是正确的,但您必须将这些字节提供给HttpServletResponse
对象
有关完整示例,请参见
关于Window.open()
您可以在客户端使用Window.open()
在新窗口中打开网页。例如:
Window.open("data:application/pdf;base64,"+ Base64.encodeBytes(result),"_parent", "location=no");
window.open("http://www.itextpdf.com");
您可以提供包含此代码段的页面,但在您的情况下,您必须替换http://www.itextpdf.com
使用为servlet定义的URL
您可能已经在这里找到了“解决方案”:
但是,如果您阅读这些评论,您会注意到这种方法在与某些浏览器结合使用时存在问题。错误#1:
让我们从一个不涉及iText的小测试开始。尝试以下方法:
byte[] test = "Test".getBytes();
System.out.println("Test " + test);
输出中写入了什么?在我的例子中,它是:
Test [B@3da3da69
[
表示我正在尝试将数组转换为字符串;B
表示数组包含字节;@
将类型与ID分开;后面的字符是十六进制格式的ID(哈希码)。请参阅
如果result
的类型为byte[]
且您有以下行:
Window.open("data:application/pdf;base64,"+result,"_parent", "location=no");
然后,+result
产生类似于“data:application/pdf;base64[B@154“
。这没有任何意义,是吗
现在试试这个:
byte[] test = "Test".getBytes();
System.out.println("Test " + new String(test));
输出为:
Test Test
您使用的是字节[]
,就好像它是字符串一样。这是您的第一个错误
我本想说一些令人讨厌的话,因为这不是Java开发人员会犯的错误。然而,我刚刚读了你的简历,我发现你是Java新手,你(可能)正在自学如何用Java编写代码(就像我20年前做的那样),所以我审查了自己;-)
错误#2:
您无法通过以下方式替换代码来解决问题:
Window.open("data:application/pdf;base64,"+ new String(result),"_parent", "location=no");
您不能这样做,因为您正在犯第二个错误:result
中的字节表示一个二进制文件,而浏览器中的JavaScript需要一个Base64编码的文件。Base64编码用于将二进制转换为文本,反之亦然。请参阅
如果要将二进制PDF文件作为Base64编码字符串发送到浏览器,则必须对字节进行Base64编码。这可以通过此类完成:
例如:
Window.open("data:application/pdf;base64,"+ Base64.encodeBytes(result),"_parent", "location=no");
window.open("http://www.itextpdf.com");
这应该已经适用于某些浏览器,但不是所有浏览器。我不知道您在哪里使用Window.open()
,也不知道为什么要使用Base64。您可能需要详细说明一下。在我看来,这是一个坏主意
应该如何做:
通常,您将编写一个在应用程序服务器中运行的Servlet
。可以使用URL从浏览器访问该Servlet。您不需要像另一个答案中所建议的那样将生成的文件保存在服务器上(我否决了该答案,因为它没有帮助,而且完全错误)。您创建ByteArrayOutputStream
然后获取字节[]
的方法是正确的,但您必须将这些字节提供给HttpServletResponse
对象
有关完整示例,请参见
关于Window.open()
您可以在客户端上使用Window.open()