如何在响应时发送 PDF 文件
How to send PDF file on response
我正在尝试编写一个将图像转换为 PDF 文件的网络应用程序。用户发送了几张图片(JPEG、PNG),应该会收到并下载一个 PDF 文件。
目前的主要问题是我不知道如何return将 PDF 文件返回给客户端。
这是我的控制器:
@PostMapping(path = "/upload",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void uploadFiles(@RequestParam("files") MultipartFile[] files) throws IOException {
imageToPdfConversionService.convert(files);
}
这是将图像转换为 PDF 文件的服务(这里我使用 itextpdf
库):
public void convert(MultipartFile[] files) throws IOException {
List<ImageData> imagesData = Arrays.stream(files)
.map(file -> {
try {
return ImageDataFactory.create(file.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
// PdfDocument pdfDocument = new PdfDocument(new PdfWriter("ImageToPdf.pdf"));
FileOutputStream fileOutputStream = new FileOutputStream("letspdf-server/src/main/resources/documents/file.pdf");
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(fileOutputStream));
Document document = new Document(pdfDocument);
for (ImageData image : imagesData) {
Image img = new Image(image);
img.setWidth(pdfDocument.getDefaultPageSize().getWidth() - 50);
img.setAutoScaleHeight(true);
document.add(img);
pdfDocument.addNewPage();
}
pdfDocument.close();
}
此外,也许将 PDF 文件存储在某处并在生成文件时在客户端创建一个 'Download' 按钮以从存储中下载文件?
因此,首先您需要将 api 更改为 return ResponseEntity,并将生成的 pdf 转换为字节数组。我将附上一个代码片段作为示例
public static ResponseEntity<Resource> makeResponse(byte[] file, String filename, MultiValueMap<String, String> customHeaders) {
MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
HttpHeaders headers = new HttpHeaders();
if (StringUtils.isNotEmpty(filename)) {
try {
mediaType = MediaType.valueOf(MIME_TYPES.detect(filename));
} catch (Exception var6) {
}
ContentDisposition contentDisposition = ContentDisposition.builder("attachment").filename(filename, StandardCharsets.UTF_8).build();
headers.setAccessControlExposeHeaders(ACCESS_CONTROL_EXPOSE_HEADERS);
headers.setContentDisposition(contentDisposition);
}
if (customHeaders != null && !customHeaders.isEmpty()) {
headers.addAll(customHeaders);
}
ByteArrayResource body = null;
if (file != null) {
body = new ByteArrayResource(file);
}
return ((BodyBuilder)ResponseEntity.ok().headers(headers)).contentType(mediaType).body(body);
}
我正在尝试编写一个将图像转换为 PDF 文件的网络应用程序。用户发送了几张图片(JPEG、PNG),应该会收到并下载一个 PDF 文件。
目前的主要问题是我不知道如何return将 PDF 文件返回给客户端。
这是我的控制器:
@PostMapping(path = "/upload",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void uploadFiles(@RequestParam("files") MultipartFile[] files) throws IOException {
imageToPdfConversionService.convert(files);
}
这是将图像转换为 PDF 文件的服务(这里我使用 itextpdf
库):
public void convert(MultipartFile[] files) throws IOException {
List<ImageData> imagesData = Arrays.stream(files)
.map(file -> {
try {
return ImageDataFactory.create(file.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
// PdfDocument pdfDocument = new PdfDocument(new PdfWriter("ImageToPdf.pdf"));
FileOutputStream fileOutputStream = new FileOutputStream("letspdf-server/src/main/resources/documents/file.pdf");
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(fileOutputStream));
Document document = new Document(pdfDocument);
for (ImageData image : imagesData) {
Image img = new Image(image);
img.setWidth(pdfDocument.getDefaultPageSize().getWidth() - 50);
img.setAutoScaleHeight(true);
document.add(img);
pdfDocument.addNewPage();
}
pdfDocument.close();
}
此外,也许将 PDF 文件存储在某处并在生成文件时在客户端创建一个 'Download' 按钮以从存储中下载文件?
因此,首先您需要将 api 更改为 return ResponseEntity,并将生成的 pdf 转换为字节数组。我将附上一个代码片段作为示例
public static ResponseEntity<Resource> makeResponse(byte[] file, String filename, MultiValueMap<String, String> customHeaders) {
MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
HttpHeaders headers = new HttpHeaders();
if (StringUtils.isNotEmpty(filename)) {
try {
mediaType = MediaType.valueOf(MIME_TYPES.detect(filename));
} catch (Exception var6) {
}
ContentDisposition contentDisposition = ContentDisposition.builder("attachment").filename(filename, StandardCharsets.UTF_8).build();
headers.setAccessControlExposeHeaders(ACCESS_CONTROL_EXPOSE_HEADERS);
headers.setContentDisposition(contentDisposition);
}
if (customHeaders != null && !customHeaders.isEmpty()) {
headers.addAll(customHeaders);
}
ByteArrayResource body = null;
if (file != null) {
body = new ByteArrayResource(file);
}
return ((BodyBuilder)ResponseEntity.ok().headers(headers)).contentType(mediaType).body(body);
}