Java文件流预览及下载(pdfjs)

需求

项目需要打印文档及图片,文件在远程文件服务器上

实现逻辑

1. 读取远程url将其转为输入流

2. 设置HttpServletResponse相关参数,将输入流转为文件流输出,支持预览

3. 2中的url在浏览器中已经可以直接预览,但是Chrome浏览器PDF查看器预览和下载使用的同一个链接,请求头不同导致下载失效。因此,此处引入pdfjs插件实现pdf预览

代码

java代码

@RequestMapping("/preview")
    public void preview(HttpServletResponse response) {

        // 模拟文件存放与文件服务器的情况
        URL url = this.getClass().getClassLoader().getResource("static/OpenOffice安装.pdf");

        String fileExt = FileUtils.getFileExt(url.getPath());

        response.reset();
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MimeTypeEnum.getMimeType(fileExt));

        response.setHeader("Content-Disposition", "inline;filename=file." + fileExt);
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Access-Control-Allow-Origin", "*");

        try (
                ServletOutputStream os = response.getOutputStream();
                InputStream is = FileUtils.readUrl(url)
        ) {
            os.write(FileUtils.streamToBytes(is));
            os.flush();
        } catch (Exception e) {
            throw new CommonException("预览失败");
        }
    }
package com.fh.hzbase.utils;

import com.fh.hzbase.bean.CommonException;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

/**
 * 文件工具类
 */
public class FileUtils {

    /**
     * 读取url
     *
     * @param urlStr
     * @return
     */
    public static InputStream readUrl(String urlStr) {
        try {
            URL url = new URL(urlStr);
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(10 * 1000);
            return connection.getInputStream();
        } catch (Exception e){
            throw new CommonException("读取文件失败", e);
        }

    }

    public static InputStream readUrl(URL url ) {
        try {
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(10 * 1000);
            return connection.getInputStream();
        } catch (Exception e){
            throw new CommonException("读取文件失败", e);
        }
    }

    public static byte[] streamToBytes(InputStream is) {
        try(ByteOutputStream bos = new ByteOutputStream()) {
            int len;
            byte[] buf = new byte[1024];
            while ((len = is.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            return bos.getBytes();
        } catch (IOException e) {
            throw new CommonException("读取流失败", e);
        }
    }

    public static String getFileExt(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }
}
package com.fh.hzbase.bean;

/**
 * @description:
 * @author: pp_lan
 * @date: 2022/3/17 10:14
 */
public class CommonException extends RuntimeException {

    public CommonException() {
    }

    public CommonException(String message) {
        super(message);
    }

    public CommonException(String message, Throwable cause) {
        super(message, cause);
    }

    public CommonException(Throwable cause) {
        super(cause);
    }

    public CommonException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

前端代码

<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <title>预览示例</title>
</head>
<body>
    <div id="app">
        <button v-on:click="preview">预览</button>
    </div>
</body>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
    var app = new Vue({
        el: "#app",
        data: {
        },
        methods: {
            preview: function() {
                var baseUrl =  'http://localhost:8080';
                //window.open(baseUrl + '/pdfjs/web/viewer.html?file=' + encodeURIComponent(baseUrl + '/OpenOffice安装.pdf'));
                window.open(baseUrl + '/pdfjs/web/viewer.html?file=' + encodeURIComponent(baseUrl + '/store/preview'));
            }
        },
        mounted: function () {
        },
        beforeDestroy: function () {

        }
    });
</script>
</html>

实现效果

 

总结:

1. 在要求简单的情况下,直接使用文件流(第2步),可以直接预览(缺点:Chrome自带的pdf查看器,点击下载会下载失败)

2. 要规避上述问题,可以引入pdfjs插件,并且可以自己定义和屏蔽功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值