我正在使用以下代码从html下载PDF包含我的工作正常,但是文件被下载了两次,我试图修改渲染器行为,但仍然没有任何内容。
public Response downloadResumePdf(@PathParam("userId") String userId) throws IOException, DocumentException {
String homePath = System.getProperty("user.home");
String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();
String yourXhtmlContentAsString = "<h1>hi </h1>";
renderer.setDocumentFromString(yourXhtmlContentAsString);
renderer.layout();
java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
renderer.createPDF(fos);
fos.close();
File file = new File(filePath);
return Response
.ok((Object) file)
.header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
.build();
答案 0 :(得分:1)
问题
在您的代码中,您正在生成一个文件,然后将其提供给您的API。该文件是用new java.io.FileOutputStream(filePath)
创建的,位于Resume2019-01-16.pdf
文件夹中的名为Downloads
。
由于您是在本地运行API,因此当您转到端点时,浏览器会将您提供的文件下载到Downloads
文件夹中。由于Resume2019-01-16.pdf
已经存在,浏览器将其命名为Resume2019-01-16 (1).pdf
。
因此,似乎正在下载两个文件,但是其中一个是由您的代码生成的,而另一个实际上是 下载的。
修复
更改正在提供的文件的文件夹,只有实际下载的文件才会出现在Downloads
中,例如:
String filePath = homePath + "/Documents/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
或者使用某种方法将文件存储在内存中,而不是创建物理文件并提供服务。
答案 1 :(得分:1)
如Mark's answer中所述,重复的原因是因为您在创建和写入FileOutputStream
时正在创建“临时”文件。
解决方案:您无需创建临时文件即可处理下载。无需创建FileOutputStream
,只需使用StreamingOutput
并将StreamingOutput
的{{1}}传递给OutputStream
方法即可。
ITextRenderer#createPDF(OutputStream)
答案 2 :(得分:0)
您使用StreamingOutput代替使用File。
String homePath = System.getProperty("user.home");
String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();
String yourXhtmlContentAsString = "<h1>hi </h1>";
renderer.setDocumentFromString(yourXhtmlContentAsString);
renderer.layout();
java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
renderer.createPDF(fos);
//fos.close();
final File file = new File(filePath);
StreamingOutput fileStream = new StreamingOutput()
{
@Override
public void write(java.io.OutputStream output) throws IOException, WebApplicationException
{
try
{
byte[] data = Files.readAllBytes(file.toPath());
output.write(data);
output.flush();
}
catch (Exception e)
{
throw new WebApplicationException("File Not Found. !!");
}
}
};
return Response
.ok( fileStream, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
.build();