最近接到一个pdf
预览的需求,但是预览内容需要有当前登录用户信息的水印。于是查了一下,发现大多都是使用pdf.js
来实现。
但是在实际使用中发现,网上大多的教程都是基于旧版本的,对于后台返回文件流的情况特别麻烦,但是在我在是选择使用较新版本的pdf.js
后却发现网上的课程有点过时,所以在这里记录自己的踩坑记录。
我使用的pdf.js
版本为2.3.200
,在pdf.js-realse下载页可以下载到。
可以直接在浏览器使用以下链接进行pdf
预览
http://127.0.0.1:5500/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/test.pdf
使用iframe
嵌套页面,需要注意一定要设置宽度和高度
@CrossOrigin //允许跨域访问
@GetMapping("{fileName}")
public ResponseEntity preview(@PathVariable("fileName") String fileName){
// 从resource目录读取文件
Resource resource = new ClassPathResource("/"+fileName);
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+handleFileName(fileName))
.body(resource);
}
/**
* 处理文件名,避免中文文件名出现乱码
* @param fileName
* @return
*/
private String handleFileName(String fileName) {
String newFileName;
try {
newFileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
newFileName = fileName;
}
return newFileName;
}
注释viewer.js
以下的源码既可
if (origin !== viewerOrigin && protocol !== 'blob:') {
throw new Error('file origin does not match viewer\'s');
}
本版本支持数据流形式预览pdf
,只需要将file
后的参数改为对应的获取pdf
文件流的url
即可
如果获取pdf
文件的url
带有参数会导致被截断,例如以下链接
http://127.0.0.1:5500/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/test.pdf&userId=test
而在实际使用的过程中却发现实际上获取pdf
的url
被截取了,变成以下这样
http://127.0.0.1:5500/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/test.pdf&userId
如果需要在获取pdf
文件流的url
中传参数,可以参考REST
风格在链接中传参,例如以下这样
http://127.0.0.1:5500/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/{userId}/test.pdf&
如果pdf
文件名为中文,建议使用以下代码对url
进行编码后使用
encodeURI('http://127.0.0.1/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/中文书名.pdf')
pdf.js
的预览页面中的菜单栏为英文,不过其自带locale
即可实现汉化,示例链接如下:
http://127.0.0.1:5500/pdfjs-2.3.200-dist/web/viewer.html?file=http://127.0.0.1:8080/test.pdf&locale=zh-CN
关键参数为locale=zh-CN
pdf.js组件的原始大小为11.6M
,按照以下方式精简后,大小为4M-5M
之间
map
文件,分别为pdf.js.map
、pdf.worker.js.map
、viewer.js.map
locale
目录下不需要的语言包,注意en-US
为默认的语言包,建议保留,其他语言包根据需要自行判断是否保留。例如我会保留zh-CN
和zh-TW
pdf
文件compressed.tracemonkey-pldi-09.pdf