java接口返回图片或pdf如何设置在线预览还是下载

一、前言

之前文章说到了如何通过将文件转成图片或者pdf来实现在线预览,一般来说在线预览图片或者pdf都是存储在图片服务器上的,在通过接口调用把文件返回给前端,但是把文件返回给前端效果一般是有两种:在线预览和下载。那这两种效果分别又该怎么实现呢?我们今天就来说这两种效果的实现。

下面是之前转成图片、pdf实现线预览,有兴趣的小伙伴可以看看。

文档在线预览(一)通过将txt、word、pdf转成图片实现在线预览功能

文档在线预览(四)将word、txt、ppt、excel、图片转成pdf来实现在线预览

其实接口实现在线预览和下载很简单,只需要通过设置content-type和Content-Disposition这两个http的响应标头就可以实现:

二、什么是Content-Disposition

Content-Disposition是HTTP协议中的一个头部字段,用于指示如何显示附加的文件。它是MIME协议的扩展,最初在MIME标准中定义。Content-Disposition头部字段可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。

在常规的 HTTP 应答中,Content-Disposition 响应标头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

multipart/form-data 类型的应答消息体中,Content-Disposition 通用标头可以被用在 multipart 消息体的子部分中,用来给出其对应字段的相关信息。各个子部分由在 Content-Type中定义的边界(boundary)分隔。用在消息体自身则无实际意义。

1、作为消息主体的标头

在 HTTP 场景中,第一个参数有以下两种

  • inline:表示回复中的消息体会以页面的一部分或者整个页面的形式展示
  • attchment:以附件形式被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将 filename 的值预填为下载后的文件名,假如它存在的话

第二个参数 filename 代表被传输的文件名称(可选)

Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"

备注: 在同源 URL情况下,Chrome 和 Firefox 82 以及更高的版本会优先使用 HTML 的 元素的 download 属性而不是 Content-Disposition: inline 参数来处理下载。而 Firefox 的早期版本则优先使用标头信息并内联显示内容。

2、作为多部分主体的标头

当使用 multipart/form-data 格式提交表单数据(HTTP 表单及 POST 请求)时,每个子部分(例如每个表单字段和任何与字段数据相关的文件)都需要提供一个 Content-Disposition 标头,以提供相关信息。标头的第一个参数始终为 form-data,并且还必须包含一个 name 参数来标识相关字段。,以及可选的第三个参数 filename

Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"

三、代码实现

下面将通过代码演示通过设置content-type响应标头来实现图片、pdf的在线预览和下载。

1、工具类

因为返回的代码基本一样所以封装了一个公共方法,后面代码将通过调用这个公共方法来演示,这个公共方法使用了tika用于根据文件流推断contentType所以需要引入下面的pom依赖,此外这里还踩了一个小坑,在文件名为中文中文时会出现乱码的情况,所以这里使用了URLEncoder.encode先对文件名进行了url转码来解决这个问题。

1.1 依赖的pom

	<dependency>
      <groupId>org.apache.tika</groupId>
      <artifactId>tika-core</artifactId>
      <version>1.28.4</version>
    </dependency>

1.2 所用到的工具类代码:

import org.apache.tika.Tika;
import org.springframework.http.*;
import java.net.URLEncoder;

public class HttpUtil {
    public static ResponseEntity<?> getResponseEntity(byte[] fileContent, String contentDispositionType, String originalFileName){
        ResponseEntity.BodyBuilder responseEntity = ResponseEntity.ok();
        HttpHeaders httpHeaders = new HttpHeaders();
        Tika tika = new Tika();
        String mediaType = tika.detect(fileContent);
        httpHeaders.setContentType(MediaType.parseMediaType(mediaType));
        httpHeaders.setContentDisposition(ContentDisposition.builder(contentDispositionType)
                .filename(URLEncoder.encode(originalFileName)).build());//解决文件名中文乱码的问题
        httpHeaders.setCacheControl(CacheControl.noCache());
        //httpHeaders.setCacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES));
        return responseEntity.headers(httpHeaders).body(fileContent);
    }
}

2、图片的预览和下载

2.1 图片预览

@GetMapping(value = "/image/review")
public ResponseEntity<?> imageReview() throws IOException {
    File file = new File("D:\\picture\\美女\\aa37a7be4196c07f43a3f776801d1b46.jpg");
    try (FileInputStream fileInputStream = new FileInputStream(file)) {
        byte[] buf = new byte[fileInputStream.available()];
        fileInputStream.read(buf);
        return HttpUtil.getResponseEntity(buf, "inline", "aa37a7be4196c07f43a3f776801d1b46.jpg");
    }
}

实现效果:请添加图片描述

2.2 图片下载

@GetMapping(value = "/image/down")
public ResponseEntity<?> imageDown() throws IOException {
    File file = new File("D:\\picture\\美女\\aa37a7be4196c07f43a3f776801d1b46.jpg");
    try (FileInputStream fileInputStream = new FileInputStream(file)) {
        byte[] buf = new byte[fileInputStream.available()];
        fileInputStream.read(buf);
        return HttpUtil.getResponseEntity(buf, "attachment", "aa37a7be4196c07f43a3f776801d1b46.jpg");
    }
}

实现效果:
请添加图片描述

3、pdf预览和下载

3.1 pdf预览

@GetMapping(value = "/pdf/review")
public ResponseEntity<?> pdfReview() throws IOException {
    File file = new File("D:\\书籍\\电子书\\其它\\自然哲学的数学原理.pdf");
    try (FileInputStream fileInputStream = new FileInputStream(file)) {
        byte[] buf = new byte[fileInputStream.available()];
        fileInputStream.read(buf);
        return HttpUtil.getResponseEntity(buf, "inline", file.getName());
    }
}

实现效果:
请添加图片描述

3.2 pdf下载

@GetMapping(value = "/pdf/down")
public ResponseEntity<?> pdfDown() throws IOException {
    File file = new File("D:\\书籍\\电子书\\其它\\自然哲学的数学原理.pdf");
    try (FileInputStream fileInputStream = new FileInputStream(file)) {
        byte[] buf = new byte[fileInputStream.available()];
        fileInputStream.read(buf);
        return HttpUtil.getResponseEntity(buf, "attachment", file.getName());
    }
}

实现效果:
请添加图片描述

4、通用预览和下载

我们可以看出上面的代码除了文件流的数据来源以外,代码都是一样的,所以结合通用的文件服务我们很容易写出一个通用文件的下载和在线预览接口了。

4.1 通用预览的伪代码

非pdf文件可先转成pdf文件来实现通用预览,文件转pdf的方法可以参考这篇文章:《文档在线预览(四)将word、txt、ppt、excel、图片转成pdf来实现在线预览》

@GetMapping(value = "/pdf/review/{fileKey}")
public ResponseEntity<?> pdfReview(@PathVariable String fileKey) throws IOException {
    //根据文件key去文件服务获取文件
    byte[] buf = getFileByteArr(fileKey);
    //文件统一转换成pdf
    byte[] pdfBuf = fileCovert.toPdf(buf);
    fileInputStream.read(buf);
    return HttpUtil.getResponseEntity(buf, "inline", file.getName());
}

4.2 通用下载的伪代码

@GetMapping(value = "/pdf/down")
public ResponseEntity<?> pdfDown() throws IOException {
     //根据文件key去文件服务获取文件
    byte[] buf = getFileByteArr(fileKey);
    fileInputStream.read(buf);
    return HttpUtil.getResponseEntity(buf, "attachment", file.getName());
}

参考资料:Content-Disposition - HTTP | MDN

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Java 中可以使用一些库来实现 PDF 预览接口。以下是一种常见的方法: 1. Apache PDFBox:Apache PDFBox 是一个开源的 Java 库,可以用来处理 PDF 文件。你可以使用它来加载和渲染 PDF 文件,并将其展示在用户界面上。你可以通过以下代码来实现预览接口: ```java PDDocument document = PDDocument.load(new File("path/to/pdf/file.pdf")); PDFRenderer renderer = new PDFRenderer(document); // 渲染第一页 BufferedImage image = renderer.renderImageWithDPI(0, 300); // 将 BufferedImage 展示在用户界面上 // 例如,使用 Swing 的 JLabel 组件 JLabel label = new JLabel(new ImageIcon(image)); JFrame frame = new JFrame(); frame.getContentPane().add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); ``` 这里使用了 PDFRenderer 类从 PDFBox 中获取渲染器,然后使用 `renderImageWithDPI` 方法渲染第一页的图像。你可以根据需要来选择渲染的页数和 DPI。 2. iText:iText 是另一个流行的 Java PDF 处理库。你可以使用它来加载、处理和展示 PDF 文件。以下是一个简单的代码示例: ```java PdfReader reader = new PdfReader("path/to/pdf/file.pdf"); PdfDocument document = new PdfDocument(reader); // 获取第一页 PdfPage page = document.getPage(1); // 将页面转换为图像 BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 300); // 将 BufferedImage 展示在用户界面上 // 例如,使用 Swing 的 JLabel 组件 JLabel label = new JLabel(new ImageIcon(image)); JFrame frame = new JFrame(); frame.getContentPane().add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); ``` 这里使用了 PdfReader 类从 iText 中读取 PDF 文件,并使用 PdfDocument 类来加载和处理 PDF 文档。然后,我们获取第一页并将其转换为图像,最后展示在用户界面上。 请注意,以上示例只是简单的演示了如何预览 PDF 文件。你可以根据自己的需求进一步扩展和定制这些代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知北游z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值