- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图将 iText 生成的 PDF 从服务器端返回到客户端,以便用户能够存储它。我正在关注How to convert iTextPDF Document to Byte Array (AceFunk)
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,[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
[
表示我正在尝试将数组转换为 String
; B
表示数组包含字节; @
将类型与 ID 分开;后面的字符是十六进制格式的 ID(哈希码)。请参阅 Java: Syntax and meaning behind "[B@1ef9157"? Binary/Address?
如果 result
的类型为 byte[]
并且您有以下行:
Window.open("data:application/pdf;base64,"+result,"_parent", "location=no");
然后 "data:application/pdf;base64,"+result
会产生类似 "data:application/pdf;base64,[B@154"
的结果。这没有任何意义,不是吗?
现在试试这个:
byte[] test = "Test".getBytes();
System.out.println("Test " + new String(test));
输出为:
Test Test
您使用的是byte[]
,就好像它是String
。这是您的第一个错误。
我本来想说一些难听的话,因为这不是 Java 开发人员会犯的错误。然而,我刚刚读了你的简历,我发现你是 Java 新手,并且你(可能)正在自学如何用 Java 编写代码(就像我 20 年前所做的那样),所以我对自己进行了审查;-)
错误#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 从浏览器访问该 servlet。 您不需要按照其他答案中的建议将生成的文件保存在服务器上(我否决了该答案,因为它没有帮助并且完全错误)。您创建 ByteArrayOutputStream
然后获取 byte[]
的方法是正确的,但您必须将这些字节提供给 HttpServletResponse
对象。
请参阅 How can I serve a PDF to a browser without storing a file on the server side? 了解完整示例。
关于 Window.open()
您可以在客户端使用Window.open()
,在新窗口中打开网页。例如:
window.open("http://www.itextpdf.com");
您可以提供包含此代码段的页面,但在您的情况下,您必须将 http://www.itextpdf.com
替换为为您的 servlet 定义的 URL。
您可能在这里找到了您的“解决方案”:Opening PDF String in new window with javascript
但是如果您阅读评论,您会发现这种方法在与某些浏览器结合使用时会出现问题。
关于java - 如何向客户端返回iText PDF文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39885410/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!