使用pdf.js在线预览 PDF (本地文件,服务器文件)
前言
不使用插件直接进行pdf预览时,对于小文件没有任何问题,但在预览一个305M,近400页的pdf文件时,打开pdf直接拉到最后几页,会造成浏览器崩溃,于是尝试使用pdf.js的插件方式进行pdf预览,解决大文件浏览器崩溃的问题。
1、下载地址
http://mozilla.github.io/pdf.js/
主要用到里边的 viewer.js 和 viewer.html 文件
2、打开文件夹,把这两个文件放进程序,一个是 build,一个是 web 文件夹,建议整个文件夹都放进去!到这差不多安装过程就 ok 了,viewer.html 文件里边有默认的 PDF 文件
测试方法 window.open(' ../pdf/web/viewer.html')
3、找到刚刚放入程序的文件,打开 web 文件目录,打开 viewer.js 文件找到他默认展示的 PDF 文件的路径改为 value:’’ ( 也可以不修改 )
4、想要调用这个 JS 来预览 PDF ,方法跟上方测试方法差不多,只不过多加了一个条件
调用方法:windows.open("/pdf/web/viewer.html?file=file.pdf");
这个方法只能读取你 web 目录下的文件,如果想要读取你本地文件或者服务器文件 就 通过流的方式输出
5、获取本地/服务器文件
前端写法:通过点击事件触发预览
previewURL: 项目地址路径
filePath: 要打开的项目
encodeURIComponent:用于 url 特殊字符的转译(比如 : ; / ? : @ & = + $ , # 这些用于分隔 URI 组件的标点符号)
// 点击调用预览方法
function xx(filePath){
var previewURL= "127.0.0.1:8080/";
window.open('../pdf/web/viewer.html?file='+encodeURIComponent(previewURL+"/test?url="+filePath));
}
后端写法:拿到文件地址,通过流的方式输出到移动端页面显示
// 通过文件流的方式预览 PDF 文件
@RequestMapping(value = "test")
public void pdfStreamHandeler(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// 获取路径
String filePath = request.getParameter("url");
File file = new File(filePath);
byte[] data = null;
try {
// 编辑请求头部信息
// 解决请求头跨域问题(IE兼容性 也可使用该方法)
response.setHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/pdf");
FileInputStream input = new FileInputStream(file);
data = new byte[input.available()];
input.read(data);
response.getOutputStream().write(data);
input.close();
} catch (Exception e) {
}
}
下面是我的项目中的调用方式:
/**
* 预览PDF
*/
@RequiresPermissions("dagl:pdf")
@Log(title = "PDF预览", businessType = BusinessType.DELETE)
@GetMapping("/pdfPreview/{dh}")
public String pdfPreview(@PathVariable("dh") String dh, ModelMap mmap)
{
mmap.put("pdf_url", fileReadUrl+dazlxxb.getPdfUrl());
return prefix + "/pdfPreview";
}
<!DOCTYPE html>
<html style="height: 100%" lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<link th:href="@{/css/update.css}" rel="stylesheet"/>
<th:block th:include="include :: header('PDF预览')"/>
<th:block th:include="include :: datetimepicker-css"/>
</head>
<body class="white-bg">
<iframe style="width: 100%;height: 100%;" frameborder="0" id="pdfView"></iframe>
</body>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:inline="javascript">
var pdf_url = [[${pdf_url}]];
var prefix = "/dagl";
$('#pdfView').attr('src', '/pdf/web/viewer.html?file=' + encodeURIComponent(prefix +"/pdfStreamHandeler?pdf_url=" + pdf_url));
</script>
</html>
// 通过文件流的方式预览 PDF 文件
@RequestMapping(value = "pdfStreamHandeler")
public void pdfStreamHandeler(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// 获取路径
String filePath = request.getParameter("pdf_url");
try {
if(StringUtils.isNotBlank(filePath)) {
byte[] data = fileDfsUtil.downLoadFile(filePath);
// 编辑请求头部信息
// 解决请求头跨域问题(IE兼容性 也可使用该方法)
response.setHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/pdf");
response.getOutputStream().write(data);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Component
public class FileDfsUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FileDfsUtil.class);
@Resource
private FastFileStorageClient storageClient ;
/**
* 上传文件
*/
public String upload(MultipartFile multipartFile,String fileName) throws Exception{
StorePath storePath = storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(),
FilenameUtils.getExtension(fileName), null);
return storePath.getFullPath() ;
}
/**
* 删除文件
*/
public String deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return "fileUrl == >>文件路径为空...";
}
try {
StorePath storePath = StorePath.parseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (Exception e) {
return e.getMessage();
}
return "OK";
}
public byte[] downLoadFile(String filePath){
StorePath storePath = StorePath.parseFromUrl(filePath);
return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
}
}
6、测试界面
7、常见问题
1).跨域错误:file origin does not match viewer’s
解决方式:找到 viewer.js 中下方的这段代码注释掉
2).找不到文件错误:这个问题原因是因为没有获取到你本地或者服务器文件,也就是 pdf > web 目录里没有这个 pdf ,因为它默认是获取这个目录下的 pdf 文件
解决方式:获取本地文件或者服务器文件路径,通过流的方式输出到页面上
3).文件损坏无法显示问题:出现这个问题一般都是你的 url 没有进行转码就直接请求到浏览器了,然后 url 存在的特殊字符会会让浏览器误认为你这个不是一个完整的链接
解决方式:查看前端访问的路径是否使用 encodeURIComponent 转码
8、如何隐藏插件自带的下载和打印功能?打开 viewer.html 文件,搜索 <button id="download"
在这个 button 按钮加上一个属性 style="visibility:hidden"
就 ok 了,如下图
原文地址:https://www.cnblogs.com/songyaru/p/15078091.html
- 报告称10后已变成出境游“老司机”屌丝80后:我还没出过国
- 担心人工智能取代你的工作?听听微软科学家怎么说!
- Radiant: 基于Ruby on Rails的内容管理系统
- “大数据”如何追回1.3亿元税款?
- Enterprise Library深入解析与灵活应用(5):创建一个简易版的批处理执行器,认识Enterprise Library典型的配置方式和对象创建方式
- BTC.com时讯-IBM等老牌大企业因区块链技术获得新活力
- Kit 3D 更新
- Enterprise Library深入解析与灵活应用(5):创建一个简易版的批处理执行器,认识Enterprise Library典型的配置方式和对象创建方式
- 晚上好啊!这是今天人工智能精选要闻
- 构建Flex应用的10大误区
- Flex的起步推动新语言学习
- 简单科普云计算相关内容
- Silverlight初级教程-开发工具
- WCF的Binding模型之五:绑定元素(Binding Element)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android仿简书搜索框效果的示例代码
- Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)
- Android开发自定义TextView省略号样式的方法
- Android开发中获取View视图宽与高的常用方法小结
- Android判断字符串中是否含字母、中文或数字
- 利用Kotlin开发你的第一个Android应用
- Android Picasso使用高斯模糊处理的示例代码
- Android RecyclerView打造悬浮效果的实现代码
- Android选择图片或视频进行循环播放
- Android第三方登录之QQ登录
- Android利用CountDownTimer实现验证码倒计时效果实例
- Android开发实现读取Assets下文件及文件写入存储卡的方法
- Android studio实现刮刮乐的方法
- Android studio圆形进度条 百分数跟随变化
- Android中的SpannableString与SpannableStringBuilder详解