本文讲的是在线预览服务器中pdf。若是值查看固定的(项目中的)pdf的话直接看官网,这里不再说明。
1.首先下载pdf.js
https://github.com/mozilla/pdf.js
下载后放入工程的静态文件目录,主要有build和web两个文件夹,其中web有两个js(getpdfInfo.js和jquery.min.js)是我自己后来加的
2.在点击预览的页面(我的是jsp页面)写点击预览跳转页面:
参数说明:pdfUrl是循环动态的服务器中的pdf地址,path是当前请求的前缀
//点击pdf预览
function openPDF(url){
window.open(path+"static/mobile/approval/web/viewer.html?pdfUrl="+url+"&path="+path);
}
3.在viewer.html页面调用viewer.js页面接收这两个参数
<script src="jquery.min.js"></script>
<!--获取html传的参数-->
<script type="text/javascript">
function GetQueryString(name)
{
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]);
return null;
}
var pdfurl=GetQueryString("pdfUrl");
var path=GetQueryString("path");
</script>
<script src="getpdfInfo.js"></script>
在接收参数前调用了Jquery.min.js,因为在下面getpdfInfo.js里是需要调用ajax去后台,以读取pdf文件流的方式获取pdf文件。
4.getpdfInfo.js代码如下
//获取pdf文件流
var DEFAULT_URL = "";//注意,删除的变量在这里重新定义
var PDFData = "";
$.ajax({
type:"post",
async:false, //
mimeType: 'text/plain; charset=x-user-defined',
url:path+"/approval/getPdf.do?pdfurl="+pdfurl,
success:function(data){
PDFData = data;
}
});
var rawLength = PDFData.length;
//转换成pdf.js能直接解析的Uint8Array类型,见pdf.js-4068
var array = new Uint8Array(new ArrayBuffer(rawLength));
for(i = 0; i < rawLength; i++) {
array[i] = PDFData.charCodeAt(i) & 0xff;
}
DEFAULT_URL = array;
这步很简单,就发送ajax请求。
5.相应的后台代码:
/**
* 获取远程服务器pdf的文件流
* @param request
* @param response
*/
@RequestMapping(value = "/getPdf")
@ResponseBody
public void getPdfInfo(HttpServletRequest request, HttpServletResponse response) {
String pdfUrl=request.getParameter("pdfurl");
logger.info("<==class:ApprovalController|getPdfInfo|pdfUrl:"+pdfUrl);
if(!StringUtils.isBlank(pdfUrl)){
InputStream fis=null;
try {
try {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
URL url=new URL(pdfUrl);
//打开请求连接
URLConnection connection = url.openConnection();
HttpURLConnection conn=(HttpURLConnection) connection;
conn.setConnectTimeout(20000);
conn.setReadTimeout(20000);
conn.connect();
response.setContentType("application/pdf");
ServletOutputStream sos=response.getOutputStream();
fis=conn.getInputStream();
int b;
while((b=fis.read())!=-1){
sos.write(b);
}
sos.close();
fis.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
(注意:这里的参数pdfUrl是浏览器直接可以访问的连接,格式是ip+端口加图片地址后缀,这样读取方式有时候会有问题(网络连接超时等问题)。这里建议用下面方式读取,即取绝对路径(路径可做成系统参数+图片路径)比如"/usr/etc/img/aaa.jpg"形式读取)
代码如下
/**
* 获取远程服务器pdf的文件流
* @param request
* @param response
*/
@RequestMapping(value = "/getPdf")
@ResponseBody
public void getPdfInfo(HttpServletRequest request, HttpServletResponse response) {
String pdfUrl=request.getParameter("pdfurl");
if(!StringUtils.isBlank(pdfUrl)){
String filePath = reimburseService.getReimburseString("reimburse.img.path");//获取系统参数
pdfUrl=pdfUrl.substring(pdfUrl.lastIndexOf("/"),pdfUrl.length());
pdfUrl=filePath+pdfUrl; //拼接系统参数和图片路径
}
logger.info("<==class:ApprovalController|getPdfInfo|pdfUrl:"+pdfUrl);
File file = new File(pdfUrl);
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) {
logger.error("class:ApprovalController getPdfInfo error:" + e.getMessage());
}
}
因为这个变量DEFAULT_URL我们重新在getpdfInfo.js定义读取了。
这样基本就可以了。不管是pc端还是手机端的h5都有成功预览的。顺便提一下,ios可以用直接预览。
所以如果写在手机端的话,之前那个页面(第二步)可以分别对安卓和ios分类操作:
//点击pdf预览
function openPDF(url){
//判断终端
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; // android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); // ios终端
if (isAndroid) {
window.open(path+"static/mobile/approval/web/viewer.html?pdfUrl="+url+"&path="+path);
}
else
{
window.location.href = 'http://localhost/goPdfView/'+url;
}
}