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

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

@PostMapping(value = "/preview")@ResponseBodypublic 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) {}

前端修改如下

 let base64 = resBase64.data.base64;base64 = base64.replace(/[\n\r]/g, '')const raw = window.atob(base64)const rawLength = raw.lengthconst 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);