前端要预览服务器PDF 可直接将要blob流返回给前端 即可用浏览器自带pdf预览功能打开,现有两种方式

方式1 返回blob流给前端 代码如下       

    @PostMapping(value = "/preview")
    @ResponseBody
    public void showPdf(HttpServletResponse response) {
        try {
            File file = new File("filePath");
            OutputStream out = null;
            try (BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
            ) {
                byte[] bs = new byte[1024];
                int len;
                response.reset(); // 非常重要
                URL u = new URL("file:///" + "filePath");
                String contentType = u.openConnection().getContentType();
                response.setContentType(contentType);
                response.setHeader("Content-Disposition", "inline;filename="
                        + "preview.pdf");
                out = response.getOutputStream();
                while ((len = br.read(bs)) > 0) {
                    out.write(bs, 0, len);
                }
                out.flush();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

此时 前端解析可直接拿返回的文件流 例子如下

let blob = this.response;
          const binaryData = [];
          binaryData.push(blob);
          const url = window.URL.createObjectURL(new Blob(binaryData, { type: 'application/pdf' }));
          window.open(url);

但有的时候 不想返回文件流 可把文件返回为base64 (注意 base64可能超长)此时代码修改如下

        File file = new File("filePath");
            OutputStream out = null;
            try (BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
                         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            ) {
                int len;
                URL u = new URL("file:///" + "filePath");
                String contentType = u.openConnection().getContentType();
                byte[] buffer = new byte[1024];
                //每次读取的字符串长度,如果为-1,代表全部读取完毕
                //使用输入流从buffer里把数据读取出来
                while ((len = br.read(buffer)) != -1) {
                    //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                    outStream.write(buffer, 0, len);
                }
                // 对字节数组Base64编码
                Base64Encoder base64 = new Base64Encoder();
                String base64Str = replaceEnter(base64.encode(outStream.toByteArray()));


            }
        } catch (Exception e) {
        }


public static String replaceEnter(byte[] bytes) {
    String content = new String(bytes, StandardCharsets.UTF_8);
    return content.replace("\n", "").replace("\r", "");
}

前端修改如下

 let base64 = resBase64.data.base64;
      base64 = base64.replace(/[\n\r]/g, '')
      const raw = window.atob(base64)
      const rawLength = raw.length
      const uInt8Array = new Uint8Array(rawLength)
      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      const url = window.URL.createObjectURL(new Blob([uInt8Array], { type: resBase64.data.contentType }));
      window.open(url);

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐