当前位置:   article > 正文

在vue中对pdf进行操作,如:预览、下载、打印等功能_vue报告进行pdf文件预览打印下载

vue报告进行pdf文件预览打印下载

vue项目中,有的功能需要对pdf进行操作,比如:预览、下载、打印等,但是没有组件库有pdf的插件,需要安装下载专门的pdf插件,这里对pdf操作做了整合,分享给大家。

示例使用的是vue-pdf组件库,如果大家有更好的插件可以进行交流学习~

话不多说,上代码!!!(vue基础的代码就不过多展示了)

一、安装插件

npm i vue-pdf

插件的github地址: https://github.com/FranckFreiburger/vue-pdf

二、在公共组件库新建PdfView文件夹,这里放封装好的组件,代码如下

  1. <template>
  2. <div class="pdfView">
  3. <div class="show">
  4. <!--分页显示-->
  5. <pdf
  6. ref="pdf"
  7. :src="pdfUrl"
  8. :page="pageNum"
  9. :rotate="pageRotate"
  10. @password="password"
  11. @progress="loadedRatio = $event"
  12. @loaded="onLoadSuccess"
  13. @page-loaded="pageLoaded($event)"
  14. @num-pages="pageTotalNum = $event"
  15. @error="pdfError($event)"
  16. @link-clicked="page = $event"
  17. >
  18. </pdf>
  19. <!--整页显示-->
  20. <!-- <pdf
  21. v-loading="loading"
  22. element-loading-text="拼命加载中"
  23. element-loading-spinner="el-icon-loading"
  24. element-loading-background="rgba(0, 0, 0, 0.8)"
  25. v-for="i in numPages"
  26. :key="i"
  27. :src="pdfUrl"
  28. :page="i"
  29. @error="pdfError($event)"
  30. ref="pdf"
  31. ></pdf> -->
  32. </div>
  33. <div class="pdf_footer">
  34. <div class="info">
  35. <div>当前页数/总页数:{{ pageNum }}/{{ pageTotalNum }}</div>
  36. <!-- <div>进度:{{ loadedRatio }}</div> -->
  37. <!-- <div>页面加载成功: {{ curPageNum }}</div> -->
  38. </div>
  39. <div class="operate">
  40. <el-button-group>
  41. <el-button type="primary" icon="el-icon-arrow-left" style="border-radius: 30px 0 0 30px" @click.stop="prePage">上一页</el-button>
  42. <el-button type="primary" @click.stop="nextPage" style="border-radius: 0 30px 30px 0">下一页<i class="el-icon-arrow-right el-icon&#45;&#45;right"></i></el-button>
  43. </el-button-group>
  44. <el-button-group>
  45. <el-button type="primary" style="border-radius: 30px 0 0 30px" @click="scaleD">放大</el-button>
  46. <el-button type="primary" style="border-radius: 0 30px 30px 0" @click="scaleX">缩小</el-button>
  47. </el-button-group>
  48. <!-- <el-button type="primary" @click="fileDownload(pdfUrl, 'pdf文件')">
  49. 下载
  50. <i class="el-icon-download"></i>
  51. </el-button> -->
  52. </div>
  53. </div>
  54. </div>
  55. </template>
  56. <script>
  57. import pdf from "vue-pdf";
  58. export default {
  59. name: "vue_pdf_preview",
  60. props: {
  61. // 当前pdf路径
  62. pdfUrl: {
  63. type: String,
  64. default: "",
  65. },
  66. },
  67. components: {
  68. pdf,
  69. },
  70. data() {
  71. return {
  72. // 总页数
  73. pageTotalNum: 1,
  74. // 当前页数
  75. pageNum: 1,
  76. // 加载进度
  77. loadedRatio: 0,
  78. // 页面加载完成
  79. curPageNum: 0,
  80. // 放大系数 默认百分百
  81. scale: 100,
  82. // 旋转角度 ‘90’的倍数才有效
  83. pageRotate: 0,
  84. // 单击内部链接时触发 (目前我没有遇到使用场景)
  85. page: 0,
  86. // 当前页数
  87. numPages: 1,
  88. // 预览路径
  89. localUrl: '',
  90. loading: true
  91. };
  92. },
  93. watch: {
  94. pdfUrl: {
  95. handler(newVal,oldVal) {
  96. this.localUrl = "";
  97. this.localUrl = newVal;
  98. let loadingTask = pdf.createLoadingTask(this.localUrl);
  99. loadingTask.promise.then(pdf => {
  100. this.numPages = pdf.numPages;
  101. this.loading = false;
  102. console.log('this.numPages', this.numPages)
  103. }).catch((err) => {
  104. console.error('pdf加载失败', err)
  105. })
  106. },
  107. immediate: true
  108. }
  109. },
  110. computed: {},
  111. created() {},
  112. mounted() {},
  113. methods: {
  114. onLoadSuccess(pdf) {
  115. // PDF加载成功后,可以将初始页码设置为第一页
  116. this.pageNum = 1;
  117. },
  118. //下载PDF
  119. fileDownload(data, fileName) {
  120. let blob = new Blob([data], {
  121. //type类型后端返回来的数据中会有,根据自己实际进行修改
  122. type: "application/pdf",
  123. });
  124. let filename = fileName || "pdf.pdf";
  125. if (typeof window.navigator.msSaveBlob !== "undefined") {
  126. window.navigator.msSaveBlob(blob, filename);
  127. } else {
  128. var blobURL = URL.createObjectURL(blob);
  129. // 创建隐藏<a>标签进行下载
  130. var tempLink = document.createElement("a");
  131. tempLink.style.display = "none";
  132. tempLink.href = blobURL;
  133. tempLink.setAttribute("download", filename);
  134. if (typeof tempLink.download === "undefined") {
  135. tempLink.setAttribute("target", "_blank");
  136. }
  137. document.body.appendChild(tempLink);
  138. tempLink.click();
  139. document.body.removeChild(tempLink);
  140. window.URL.revokeObjectURL(blobURL);
  141. }
  142. },
  143. //打印
  144. pdfPrintAll() {
  145. this.$refs.pdf.print();
  146. },
  147. //放大
  148. scaleD() {
  149. this.scale += 5;
  150. this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
  151. },
  152. //缩小
  153. scaleX() {
  154. // scale 是百分百展示 不建议缩放
  155. if (this.scale == 100) {
  156. return;
  157. }
  158. this.scale += -5;
  159. console.log(parseInt(this.scale) + "%");
  160. this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
  161. },
  162. // 切换上一页
  163. prePage() {
  164. var p = this.pageNum;
  165. p = p > 1 ? p - 1 : this.pageTotalNum;
  166. this.pageNum = p;
  167. },
  168. // 切换下一页
  169. nextPage() {
  170. var p = this.pageNum;
  171. p = p < this.pageTotalNum ? p + 1 : 1;
  172. this.pageNum = p;
  173. },
  174. // pdf 有密码 则需要输入秘密
  175. password(updatePassword, reason) {
  176. updatePassword(prompt('password is "test"'));
  177. console.log("...reason...");
  178. console.log(reason);
  179. console.log("...reason...");
  180. },
  181. // 页面加载成功 当前页数
  182. pageLoaded(e) {
  183. console.log("pageLoaded",e);
  184. this.$emit("current", e);
  185. this.curPageNum = e;
  186. },
  187. // 异常监听
  188. pdfError(error) {
  189. console.error('异常监听', error);
  190. },
  191. // getNumPages() {
  192. // let loadingTask = pdf.createLoadingTask(this.pdfUrl);
  193. // loadingTask.promise.then(pdf => {
  194. // this.numPages = pdf.numPages;
  195. // console.log('this.numPages', this.numPages)
  196. // }).catch((err) => {
  197. // console.error('pdf加载失败')
  198. // })
  199. // },
  200. },
  201. };
  202. </script>
  203. <style lang="scss" scoped>
  204. .pdfView {
  205. padding: 20px;
  206. .show {
  207. overflow: auto;
  208. margin: auto;
  209. max-width: 100%;
  210. //height: 80vh;
  211. max-height: 580px;
  212. border: 2px solid #eee;
  213. border-radius: 6px;
  214. background-color: #eeeeee;
  215. // 滚动条样式
  216. &::-webkit-scrollbar {
  217. width: 10px;
  218. }
  219. &::-webkit-scrollbar-thumb {
  220. background-color: #999;
  221. border-radius: 6px;
  222. }
  223. &::-webkit-scrollbar-track {
  224. background-color: transparent;
  225. border-radius: 6px;
  226. }
  227. }
  228. .pdf_footer {
  229. position: sticky;
  230. bottom: 0;
  231. left: 0;
  232. right: 0;
  233. padding: 10px 0;
  234. background-color: rgba(255, 255, 255, 0.5);
  235. .info {
  236. display: flex;
  237. flex-wrap: wrap;
  238. justify-content: space-around;
  239. div {
  240. width: 30%;
  241. }
  242. }
  243. .operate {
  244. margin: 10px 0 0;
  245. display: flex;
  246. flex-wrap: wrap;
  247. justify-content: space-between;
  248. div {
  249. // width: 80px;
  250. text-align: center;
  251. font-size: 15px;
  252. }
  253. .btn {
  254. cursor: pointer;
  255. margin: 5px 10px;
  256. width: 120px;
  257. border-radius: 10px;
  258. padding: 5px;
  259. color: #fff;
  260. background-color: #3dcbbc;
  261. }
  262. }
  263. }
  264. }
  265. </style>

这里给出了几种展示方式,有分页显示,有整页显示。按照项目需求可自行进行调整。

三、在页面你需要的地方引用

  1. import PdfView from "@/components/PdfView";
  2. import pdf from 'vue-pdf';
  3. export default {
  4. components:{pdf},
  5. data(){
  6. return{
  7. pdf_img_url: null,//pdf文件路径
  8. }
  9. },
  10. methods:{
  11. downloadPDF(){
  12. let url=this.pdf_img_url
  13. let newTab = window.open(url, '_blank');
  14. // 新窗口加载完后打印
  15. newTab.onload = function() {
  16. newTab.focus();
  17. newTab.print();
  18. };
  19. },
  20. printPdf() {
  21. console.log('this???????',this.$refs.pdf);
  22. this.$refs.pdf.pdfPrintAll()
  23. },
  24. }
  25. }
  1. <el-dialog
  2. title="PDF文件预览"
  3. :visible.sync="PdfViewVisible"
  4. append-to-body
  5. lock-scroll
  6. width="50%"
  7. :before-close="handleClosePdf"
  8. >
  9. <el-button @click="downloadPDF">下载</el-button>
  10. <i class="el-icon-printer" @click="printPdf" style="cursor: pointer;float: right;font-size: 25px;"></i>//这是打印事件
  11. <pdf-view :pdfUrl="pdf_img_url" ref="pdf" @load="onPDFLoaded"></pdf-view>
  12. </el-dialog>

我这里放在了dialog中使用,可以根据自己实际需要的场景来进行使用。

预览是在当前页面打开的,不需要打开浏览器新窗口。

打印也是在当前页面打开了打印的窗口,但是需要注意有乱码的情况产生,这时需要更改插件的源文件。如果你的项目没有要求当前页面还是新窗口打开,那可以直接使用window.print(),可以参考下载的方法,调出浏览器自带的打印、下载事件(这个比较成熟,可以直接用)。

四、运行示例

注意:pdf_img_url我这里是请求后端接口拿到的,就不展示那部分代码了。

温馨提示:关闭dialog框时,记得清除pdf文件路径,避免打开下一个时还加载的是当一个文件。

好啦,这次的分享就进行到这了。博主也是第一次使用这个插件,在不断学习中,如果有朋友发现问题可进行评论交流学习。勿喷勿喷!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/880358
推荐阅读
相关标签
  

闽ICP备14008679号