今天在项目中实现pdf在线预览的功能的如图, 通过百度,查询合适的方法,最为简单的的是通过pdf.js的插件在前台展示。本以为是挺容易实现的,但都有莫名其妙的错误。
第一步:下载源码https://github.com/mozilla/pdf.js
第二步:构建PDF.js
ps:其实我们使用pdf.js,只需要构建后的内容,大家可以到我的百度云盘下载:https://pan.baidu.com/s/10j9rqnY-vkyLRQuxCWrhfQ 提取码:gigy ;下载后复制generic到到resource/static/ 下,可以改名为pdf(自定义)
第三步:
修改viewer.js
var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf' 里面是PDF的路径,这是默认加载pdf文件的路劲
第四步:在前端js中引用(在点击事件中)
var curWwwPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
//调用pdfjs的viem.html页面来展示获得pdf
window.open(localhostPath + "/pdf/web/viewer.html?file=http://localhost:8083/previewPdf");
第四步:后台controller实现的代码
/**
* 预览pdf文件
* @param fileName
*/
@RequestMapping(value = "/previewPdf", method = RequestMethod.GET)
public void pdfStreamHandler(String fileName,HttpServletRequest request,HttpServletResponse response) {
File file = new File("E:\\"+fileName);
if (file.exists()){
byte[] data = null;
try {
FileInputStream input = new FileInputStream(file);
data = new byte[input.available()];
input.read(data);
response.getOutputStream().write(data);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}else{
return;
}
}
开始以为这样子就可以访问到本地pdf文件,我发现我错了,不知道为什么通过这种方式调用viewer.html,fileName参数传递不过来,后面我把File file = new File("E:\\test.pdf");就能在前台读取到了pdf文件。(参数不能传递过来,原因不明)。
然后我想访问ipfs上的文件,它又不知道怎么传递参数,然后我就用两个方法实现在线预览ipfs上的pdfs文件,首先先通过ipfs的文件路径获取到文件的。然后再使用一个方法把获取到的数据展现在viewer.html上。
前台代码:
//文件预览
function previewPdf(obj) {
//首先获得按钮列,然后获得行,再获得这行的所有列
var $td = $(obj).parents('tr').children('td');
//获得指定的列的值
var fileName = $td.eq(0).text();
var path = $td.eq(1).text();
var url = "http://localhost:8083/tempDownloadFile?path=" + path + "&fileName" + fileName;
$.ajax({
type: 'POST',
async: false,
url: url,
dataType: 'text',
success: function (responseText) {
if (responseText == "success") {
// alert(11)
var curWwwPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
//调用pdfjs的viem.html页面来展示获得pdf
window.open(localhostPath + "/pdf/web/viewer.html?file=http://localhost:8083/previewPdf");
}
},
error: function () {
alert('发生错误');
}
});
};
后台代码:
/**
* 预览pdf文件
*/
@RequestMapping(value = "/previewPdf", method = RequestMethod.GET)
public void pdfStreamHandler(HttpServletRequest request, HttpServletResponse response) throws IOException {
byte [] data = (byte[]) request.getSession().getAttribute("data");
if (data != null) {
response.getOutputStream().write(data);
} else {
return;
}
request.getSession().removeAttribute("data");
}
/**
* 临时缓存pdf文件用于在线浏览
* @param response
*/
@RequestMapping("/tempDownloadFile")
@ResponseBody
public void tempDownloadFile(String path , String fileName , HttpServletRequest request, HttpServletResponse response) throws IOException {
byte[] data = ipfsService.download(path);
request.getSession().setAttribute("data",data);
response.getWriter().write("success");
}
展示:
http://localhost:8083/pdf/web/viewer.html?file=http://localhost:8083/previewPdf这样子的访问就是通过后台获取的pdf的流,然后通过在前台展示。
到此pdf.js结束了,不过本人还是不清楚这样子传递参数,为什么后台没法接受到,希望各位大神告诉一下小弟。