csdn的外链图片看不了,可以看我掘金的原文:https://juejin.cn/post/7117521871221817375

一、需求

最近做项目遇到在线预览和下载pdf文件,试了多种pdf插件,例如jquery.media.js(ie无法直接浏览),最终决定用pdf.js,这篇文章记录一下我做技术选型的过程。

二、pdf预览的各种实现方式

方式一、a标签直接打开

pdf文件理论上可以在浏览器直接打开预览但是需要打开新页面。在仅仅是预览pdf文件且UI要求不高的情况下可以直接通过a标签href属性实现预览

<a href="文档地址"></a>

缺点:google的word excel ppt 预览资源,必须是公共可访问的。而且谷歌浏览器上点击就会下载,IE上可以选择是预览还是下载

方式二、通过iframe、embed、obj标签嵌入内容

1)iframe

直接通过页面内嵌iframe

$("<iframe src='"+ this.previewUrl +"' width='100%' height='362px' frameborder='1'>").appendTo($(".video-handouts-preview"));

此外还可以在iframe标签之间提供一个提示类似这样

<iframe :src="previewUrl" width="100%" height="100%">
This browser does not support PDFs. Please download the PDF to view it:
<a :href="previewUrl">Download PDF</a>
</iframe>

2)embed标签

<embed :src="previewUrl" type="application/pdf" width="100%" height="100%">

此标签h5特性中包含四个属性:高、宽、类型、预览文件src!与< iframe > < / iframe > 不同,这个标签是自闭合的的,也就是说如果浏览器不支持PDF的嵌入,那么这个标签的内容什么都看不到!

3)object标签

还有object标签,这种方式和iframe使用差别较小:

<object :src="previewUrl" width="100%" height="100%">
This browser does not support PDFs. Please download the PDF to view it: <a :href="previewUrl">Download PDF</a>
</object>

方式三、jquery.media.js插件

通过jquery插件jquery.media.js实现这个插件可以实现pdf预览功能(包括其他各种媒体文件)但是对word等类型的文件无能为力。实现方式:js代码:

<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="jquery.media.js"></script>

html结构:

    <body><div id="handout_wrap_inner"></div></body>

调用方式:

<script type="text/javascript">  $('#handout_wrap_inner').media({width: '100%',height: '100%',autoplay: true,src:'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',});
</script>

方式四、PDFObject.js插件

PDFObject实际上也是通过上面说的iframe、embed、obj标签实现的

<!DOCTYPE html>
<html>
<head><title>Show PDF</title><meta charset="utf-8" /><script type="text/javascript" src='pdfobject.min.js'></script><style type="text/css">html,body,#pdf_viewer{width: 100%;height: 100%;margin: 0;padding: 0;}</style>
</head>
<body><div id="pdf_viewer"></div>
</body>
<script type="text/javascript">if(PDFObject.supportsPDFs){// PDF嵌入到网页PDFObject.embed("index.pdf", "#pdf_viewer" );} else {location.href = "/canvas";}</script>
</html>

还可以通过以下代码进行判断是否支持PDFObject预览

if(PDFObject.supportsPDFs){console.log("Yay, this browser supports inline PDFs.");
} else {console.log("Boo, inline PDFs are not supported by this browser");
}

方式五、pdf.js

我最后选择了pdf.js插件(兼容ie10及以上、谷歌、安卓,苹果),强烈推荐该插件,下面介绍用法。

pdf.js在vue中的使用:

1)下载插件

下载路径:https://github.com/mozilla/pdf.js
百度网盘下载
链接:https://pan.baidu.com/s/1z4_o8ahN3JNifSnALbKLeg
提取码:7efu

2)将下载构建后的插件放到文件中public(vue/cli 3.0)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tSHnHJec-1657177427327)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7b4d9fd57c30444b9a4efc7e76356452~tplv-k3u1fbpfcp-zoom-1.image)]

3)在vue文件中直接使用,贴上完整代码

<template><div class="wrap"><iframe :src="pSrc" width="100%" height="100%"></iframe></div>
</template>
<script>export default {name: "pdf",data() {return {pSrc: '',};},methods: {loadPDF() {//baseurl :pdf存放的文件路径,可以是本地的,也可以是远程,这个是远程的,亲测可以用// ie有缓存加个随机数解决let baseurl = 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf';let pSrc = baseurl + '?r=' + new Date();this.pSrc = '../../plugin/pdf/web/viewer.html?file=' + encodeURIComponent(pSrc) + '.pdf';},},mounted: function () {this.loadPDF();}};
</script>
<style scoped>.wrap {position: fixed;top: 0;left: 0;width: 100%;bottom: 0;}
</style>

好啦,现在我们把dom添加到页面中,打开页面就可以看到预览了

4)效果

这边给个在线链接:http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf,
大家可以试试,最终效果是这样的:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F1fv3bb6-1657177427328)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3b20f1495e7c4834bd97e761853ffcdb~tplv-k3u1fbpfcp-zoom-1.image)]

5)如何魔改?

下面我举个例子,来讲讲怎么魔改展示页面。
比如说,如果你想要的禁掉pdf文件的下载、打印等功能,最简单的方法是,找的自己导入文件里的viewer.html,路径为build下的generic文件夹下的web里的viewer.html,如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0sW0gnD-1657177427328)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fcf8a27d1fba40d1b2cb2f347bae6b53~tplv-k3u1fbpfcp-zoom-1.image)]
在这个html里找到对应下载的dom直接display:none就可以,切记不可以注掉,注掉会报错。如下,红色框中,一个是下载一个是打印,直接隐藏就可以。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJQoZhcg-1657177427328)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58990b51e5ca4663ad42907189ae3239~tplv-k3u1fbpfcp-zoom-1.image)]
如果有人问这样也不安全,那可以和客户商量不在页面展示,因为只要页面可以看到的东西,截屏也可以截下来,注定是不安全的。

6)踩坑注意事项

踩坑1:如果url中含有中文,则需要转码

关于文件地址的url,如果包含中文,需要转码,我们尽量进行转码,pdf会自动解码,这样靠谱一点

var downloadUrl = baseUrl + 'xxx/接口地址?token=' + this.token + '&filePath='+paymentFiles[i].FILE_PATH+'&fileName='+paymentFiles[i].FILE_NAME;
//由于地址需要传文件名字和路径 文件名字包含中文,所以需要转码
var url = encodeURIComponent(downloadUrl); //获取pdf预览地址
//把文件流地址天津到file参数中
url = "/libs/DPFjs/web/viewer.html?file=" + url;
//把dom添加到页面中,打开页面即可显示
accountingArchivesQuery_ViewHTML+= '';

如果不进行转码就会出现以下错误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDeYopuv-1657177427329)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d2d3fd9e91ba48909ef65e847111ba4a~tplv-k3u1fbpfcp-zoom-1.image)]

踩坑2:把文件地址赋值给file,打开浏览器跨域报错

这个的原因是因为viewer.js中有跨域判断的代码注释掉就好了

但是有一些场景后台给我返回的数据是base64格式,如果是base64数据的pdf又如何处理呢?直接使用是不ok的,pdf不支持base64,继续折腾。

踩坑3:PDF.js默认不支持pdf base64格式数据的预览

解决方法修改源码,让pdf.js支持base64位数据,但是这里有一个大坑(IE不兼容…),不知道各位使用之后有没有同样问题,
[RFC2045]中有规定:Base64一行不能超过76字符,超过则添加回车换行符。因此需要把base64字段中的换行符,回车符给去掉。且需要转换成pdf.js能直接解析的Uint8Array类型
在viewer.html中引入viewer.js之前添加以下代码

var DEFAULT_URL = "";
var pdfUrl = document.location.search.substring(1);
if(null == pdfUrl || "" == pdfUrl){
varBASE64_MARKER = ';base64,';//声明文件流编码格式
var preFileId = "";
var pdfAsDataUri = sessionStorage.getItem("_imgUrl");//这里就是pdf文件的base64码,我是通过session传递base64的
var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
DEFAULT_URL = pdfAsArray;
//编码转换
functionconvertDataURIToBinary(dataURI) {
//[RFC2045]中有规定:Base64一行不能超过76字符,超过则添加回车换行符。因此需要把base64字段中的换行符,回车符给去掉。
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var newUrl = dataURI.substring(base64Index).replace(/[\n\r]/g,'');
var raw = window.atob(newUrl);//这个方法在ie内核下无法正常解析。
var rawLength = raw.length;
//转换成pdf.js能直接解析的Uint8Array类型
var array = newUint8Array(newArrayBuffer(rawLength));
for (i = 0; i < rawLength; i++) {array[i] = raw.charCodeAt(i) & 0xff;}
return array;}}

修改viewer.js中 defaultUrl 的 value 为 DEFAULT_URL

在页面中使用 把请求回来的base64数据存储到本地 sessionStorage 打开/viewer.html 自动获取本地数据进行预览

if(fileList[i].source == 'pdf'){
//使用pdf.js 预览base64格式         sessionStorage.setItem('_imgUrl',"data:application/pdf;base64,"+fileList[i].fileBase64);imageHTML = '</span></span></div></div></li><li style='list-style:none outside none;'><div style='font-size:14px;font-style:normal;font-weight:400;font-family:&quot;Source Code Pro&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Ubuntu Mono&quot;, &quot;Anonymous Pro&quot;, &quot;Droid Sans Mono&quot;, Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, sans-serif;line-height:22px;color:rgb(171, 178, 191);text-align:left;float:left;width:24px;height:22px;border-top:0px none rgb(171, 178, 191);border-bottom:0px none rgb(171, 178, 191);border-right:1px solid rgb(197, 197, 197);border-left:0px none rgb(171, 178, 191);text-decoration:none solid rgb(171, 178, 191);background:rgba(0, 0, 0, 0) none repeat 0% 0%;'></div><div style='font-size:14px;font-style:normal;font-weight:400;font-family:&quot;Source Code Pro&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Ubuntu Mono&quot;, &quot;Anonymous Pro&quot;, &quot;Droid Sans Mono&quot;, Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, sans-serif;line-height:22px;margin:0px 0px 0px 8px;color:rgb(171, 178, 191);text-align:left;float:left;width:494.312px;height:22px;border-top:0px none rgb(171, 178, 191);border-bottom:0px none rgb(171, 178, 191);border-right:0px none rgb(171, 178, 191);border-left:0px none rgb(171, 178, 191);text-decoration:none solid rgb(171, 178, 191);background:rgba(0, 0, 0, 0) none repeat 0% 0%;'><div style='font-size:14px;font-style:normal;font-weight:400;font-family:&quot;Source Code Pro&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Ubuntu Mono&quot;, &quot;Anonymous Pro&quot;, &quot;Droid Sans Mono&quot;, Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, sans-serif;line-height:22px;color:rgb(171, 178, 191);text-align:left;float:none;width:494.312px;height:22px;border-top:0px none rgb(171, 178, 191);border-bottom:0px none rgb(171, 178, 191);border-right:0px none rgb(171, 178, 191);border-left:0px none rgb(171, 178, 191);text-decoration:none solid rgb(171, 178, 191);background:rgba(0, 0, 0, 0) none repeat 0% 0%;'><span style='font-size:14px;font-style:normal;font-weight:400;font-family:&quot;Source Code Pro&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Ubuntu Mono&quot;, &quot;Anonymous Pro&quot;, &quot;Droid Sans Mono&quot;, Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, sans-serif;line-height:22px;color:rgb(152, 195, 121);text-align:left;float:none;border-top:0px none rgb(152, 195, 121);border-bottom:0px none rgb(152, 195, 121);border-right:0px none rgb(152, 195, 121);border-left:0px none rgb(152, 195, 121);text-decoration:none solid rgb(152, 195, 121);background:rgba(0, 0, 0, 0) none repeat 0% 0%;'> frameborder="0" scrolling="no" name="发票图片" >';preview_div.append(imageHTML)
}

谷歌正常预览,ie报错!

打印看一下,分析原因可能是atob(newUrl);//这个方法在ie内核下可能无法正常解析。

贯彻一把唆的原则.直接把base64流,还原成pdf,谷歌预览正常ie预览正常!!!
解决方案:把pdf base64流转pdf 前提是原本就是pdf 且pdf.js只能预览pdf 以下代码添加到后台接口返回回调

var base = fileList[i].fileBase64//要传入的base64数据
var bstr = atob(base)
var n = bstr.length;
var u8arr = newUint8Array(n);
while (n--) {u8arr[n] = bstr.charCodeAt(n);}
//确定解析格式,转换成pdf 可能可以变成img,但没有深入研究
var blob = newBlob([u8arr], {type: 'application/pdf;chartset=UTF-8'});
var url = window.URL.createObjectURL(blob)
//使用pdf.js 预览
var add = "/libs/DPFjs/web/viewer.html?file=" + url;
imageHTML = '';
preview_div.append(imageHTML)

ie也正常预览啦
好了,上面就是我推荐的方案:pdf.js的写法。

基于pdf.js封装的npm库

npm上面有基于pdf.js,开发的各种库:如pdf-vue,pdfjs.dist,vueshowpdf,下面也介绍一下:

1)vue-pdf

vue-pdf,就是对pdf.js做了vue版本的封装。

npm install --save vue-pdf

pdf 页面显示

<template><div><pdf ref="pdf":src="url"></pdf></div>
</template>

JS:

<script>
import pdf from 'vue-pdf'
export default {components:{pdf},data(){return {url:"http://image.cache.timepack.cn/nodejs.pdf",}}
</script>

缺点:
我装包的时候报错了,好像是vue-pdf这个库对webpack的版本好像有要求,解决半天无果,就直接换方案了,反正也是基于pdf.js的封装,我自己直接用pdf.js算了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lQny2hkB-1657177427329)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3dbb420667df4d5dad4c7339df6d0fe6~tplv-k3u1fbpfcp-zoom-1.image)]

2)vueshowpdf

vueshowpdf和vue-pdf一样,基于pdf.js做了二次封装,但是看了一下npm的包界面,此包已弃用,建议不使用这个方案。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwTMdIL2-1657177427329)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cc8352941a4a4bddbb65b0cff053d6da~tplv-k3u1fbpfcp-zoom-1.image)]

3)pdfjs-dist

你可以理解为pdf.js的npm版本
安装:

npm i pdfjs-dist --save-dev

使用:

import * as PDFJS from "pdfjs-dist/legacy/build/pdf";
// 设置pdf.worker.js文件的引入地址
PDFJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/legacy/build/pdf.worker.entry.js");
// data是一个ArrayBuffer格式,也是一个buffer流的数据
PDFJS.getDocument(data).promise.then(pdfDoc=>{const numPages = pdfDoc.numPages; // pdf的总页数// 获取第1页的数据pdfDoc.getPage(1).then(page =>{// 设置canvas相关的属性const canvas = document.getElementById("the_canvas");const ctx = canvas.getContext("2d");const dpr = window.devicePixelRatio || 1;const bsr =ctx.webkitBackingStorePixelRatio ||ctx.mozBackingStorePixelRatio ||ctx.msBackingStorePixelRatio ||ctx.oBackingStorePixelRatio ||ctx.backingStorePixelRatio ||1;const ratio = dpr / bsr;const viewport = page.getViewport({ scale: 1 });canvas.width = viewport.width * ratio;canvas.height = viewport.height * ratio;canvas.style.width = viewport.width + "px";canvas.style.height = viewport.height + "px";ctx.setTransform(ratio, 0, 0, ratio, 0, 0);const renderContext = {canvasContext: ctx,viewport: viewport,};// 数据渲染到canvas画布上page.render(renderContext);})
})

缺点: 这个也报错了,因为他的源码用了很多草案语法比如"?."。我编译直接报错,尝试用babel装编译包也没用,最后放弃了这个方案。
还是那句话,基于pdf.js封装的,我还不如直接用pdf.js。

三、总结

1.pdf预览的各类方案对比

那么对比完来一个总结,你也可以直接看这里:
最最最简单是,直接a标签弹外链,用浏览器自带的pdf预览。但不能改样式,也不能放在弹窗里展示。

如果只想简单在页面中嵌套 PDF,使用 iframe / object / embed等标签是最好的选择,它不需要你自己去编写翻页组件、不需要去调整样式,用户体验佳。(jquery.media.jsPDFObject.js这些库也只是把pdf转成标签展示而已,原理是一样的)

如果对权限控制、样式定制需求较高,使用pdf.js及是最好的选择,他的原理是将pdf转换成canvas,所以浏览器兼容性好。同时接口和属性较全,扩展能力强,自由度高。
至于是否使用基于pdf.js的npm库,如vue-pdfPdfjs.list,看个人意愿想不想选择二次封装的插件,我个人不太喜欢用别人二次封装的东西。

方案 优点 缺点 原理
a标签 一行代码实现功能,最最最简单 只能跳外链,且无法改UI 利用浏览器自身的pdf处理
iframe / object /embed 简单易用包含了打印、翻页、缩放等内嵌功能 无法改UI,不支持打印、复制等功能的禁用 将pdf 作为插件内嵌在这三个HTML标签内
jquery.media.js 使用方便,包含打印等内嵌功能 不支持IE,没法改UI 将pdf转化为标签
PDFObject.js 使用方便,包含打印等内嵌功能,可以判断是否支持预览 没法改UI 将pdf转化为标签
Pdf.js 对浏览器的兼容性好,只需要支持H5,支持改UI,解析功能强大,最优解! 跨域报错、不支持预览base64格式pdf文件流 解析pdf为Canvas,放到viewer.html页面来展示,所以改viewer.html就能改UI。
vue-pdf 样式组件可自定义,包含加载进度、翻页、页内元素可交互等 固定宽高的比例,包裹 PDF的父容器如果过小,则无法完全展示 基于pdf.js实现
vueshowpdf 样式简单清爽包含翻页、缩放功能,可以禁止打印 此包已弃用,建议不使用这个方案。 基于pdf.js实现
Pdfjs.list 对浏览器的兼容性好,解析功能依赖pdf.js,可以加水印 源码用了很多草案语法如?.,需要升级babel的解析包才能用 基于pdf.js

2.过程问题汇总

1)pdf 文件放在前端项目文件夹下,为何 pdf 出不来?

是因为路径问题。将 pdf 放在 public > static 下,并用 /static/xxx.pdf 的路径方式进行引用( / 即代表 public)即可。

2)pdf 放在服务器上时,访问 pdf 文件跨域

跨域问题一般是在后端这边没有配好 Access-Control-Allow-Origin 权限,我这边后端是使用 nginx 来进行代理,因此只需在 nginx 中配置好相关的跨域权限即可。具体参考文档:MDN 跨域相关文档

3)如何控制权限,让外部的人无法直接通过链接来访问 pdf?

这边有两个思路,第一个是在发起文件请求时,在头部中带 token;第二个是使用防盗链技术。

防盗链(最终解决方案)

什么是防盗链?
  浏览器在加载非本站的资源时,会增加一个头域,头域名字固定为:Referer。
  而在 直接粘贴 地址到浏览器地址栏访问时,请求的是本站的该 url 的页面,是 不会有这个 referer 这个http头域的。举个例子:
将 http://…/xxx.pdf 复制进网页地址栏中访问,在调试工具的 Network 中的 headers 看不到 Referer
通过项目中的 src 对该资源进行访问,会出现 Referer
  这个 referer 标签正是为了告诉请求响应者(被拉取资源的服务端),本次请求的引用页是谁,资源提供端可以分析这个引用者是否“友好”,是否允许其“引用”,对于不允许访问的引用者,可以不提供图片,这样访问者在页面上就只能看到一个图片无法加载的浏览器默认占位的警告图片,甚至服务端可以返回一个默认的提醒勿盗链的提示图片。
  总结:防盗链只允许在名单上的人访问,而不在名单上的人禁止访问。
如何使用防盗链?
  一般的站点或者静态资源托管站点来提供防盗链的设置,也就是让服务端识别指定的 Referer,在服务端接收到请求时,通过匹配 referer 头域与配置,对于 指定放行,对于其他 referer 视为盗链。
  因此,在服务端配置相关防盗链配置,并 放行前端访问的IP 即可(这里因为是后端同学配的,感兴趣的同学自行上网搜索下如何配置)
  
参考网址:https://juejin.cn/post/6844903561017425927#heading-0
https://juejin.cn/post/7071598747519549454
https://juejin.cn/post/6844904089076269070
https://blog.csdn.net/weixin_42678675/article/details/109736497

这将是你看到过最全的pdf预览解决方案相关推荐

  1. vue3 - 【完整源码】超详细实现网站 / H5 在线预览 pdf 文件功能,支持缩放、旋转、全屏预览、打印、下载、内容检索、主题色定制、侧边缩略图、页码跳转等等(最好用的pdf预览器,注释详细!)

    效果图 在 Vue3.js 项目中,实现了快速高效的 pdf 预览器工具组件,附带详细的使用教程与详细的注释,保证一键复制轻松搞定! 详细的注释很容易二次修改,很多实用功能,你也可以自定义界面上的样式 ...

  2. vue-pdf+element实现全屏窗口pdf分页预览,pdf打印实现和解决打印乱码

    一.源码 vue-pdf打印实现和乱码解决https://download.csdn.net/download/lucky_fang/85498529 二.全屏窗口打印预览效果 分页预览pdf 窗口采 ...

  3. uni-app 轮播图视频+图片 视频图片全屏预览 两种方法

    项目场景: 在做商城项目的时候,商品详情的轮播图需要同时显示视频和图片,并且能够全局预览 解决方案: 如果项目里有uview这个组件库,可以通过swiper轮播图的指定类型进行解决,点击这里进行跳转 ...

  4. 公有云运维安全常见四大难题及解决方案

    公有云运维安全常见四大难题及解决方案 参考文章: (1)公有云运维安全常见四大难题及解决方案 (2)https://www.cnblogs.com/aliyunblogs/p/5193127.html ...

  5. linux多线程九宫格,项目实战:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)...

    需求 做嵌入式设备,需求九宫格图片资源浏览器: 1.设置根目录: 2.可拖动: 3.可设置列数与行数: 4.点击文件夹可以进入文件夹: 5.点击图片可以浏览图片: 6.支持触摸屏上下拽拖浏览: 7.支 ...

  6. 【报告分享】企业出海全知道.pdf(附80页pdf下载链接)

    大家好,我是文文(微信:sscbg2020),今天给大家分享微软和久谦于2020年10月份联合发布的报告<企业出海全知道.pdf>,做出海市场的伙伴们可以重点参考下. 近年,随着国家&qu ...

  7. android 摄像头比例,Android摄像头是全屏预览最简单的方式.doc

    Android摄像头是全屏预览最简单的方式 Android Camera做全屏预览之最简单方法 M厂开发五部:刘 博 一.全屏预览与非全屏预览的区别 对于大多数人来说,我们看电影.玩游戏等都喜欢全屏, ...

  8. 手机端点击图片全屏预览

    <!doctype html> 手机端点击图片全屏预览 <div class="category"><img src="1.jpg" ...

  9. android从九宫格全屏预览,仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图...

    AssNineGridView 仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图(可自定义). 写在前面 这是一个九宫格控件,本来是很久之前就写好了,现在才开源出来,也是看了很多优秀 ...

  10. android camera 全屏,Android Camera做全屏预览之最简单方法.doc

    Android Camera做全屏预览之最简单方法 M厂开发五部:刘 博 一.全屏预览与非全屏预览的区别 对于大多数人来说,我们看电影.玩游戏等都喜欢全屏,我们之所以喜欢全屏的一个主要原因就是全屏的感 ...

最新文章

  1. 关于JS客户端对服务器控件赋值,Post后不能保留值的解决办法
  2. Linux新手上路命令
  3. td 超出部分怎么显示_道瑞斯:黄金白银TD走势分析(纸黄金,纸白银,现货黄金,现货白银)...
  4. 腐蚀rust服务器命令_【使用 Rust 写 Parser】2. 解析Redis协议
  5. mysql8和php7不能连接_php无法连接mysql8.x
  6. python datetime和字符串如何相互转化?
  7. 使用Genymotion Android模拟器无法连接电脑本机的服务器
  8. 运行python时说要建如版权_当我运行python manage.py syncdb时,Django避免在数据库中创建PointField...
  9. IIS架设FTP服务器图文教程
  10. abap 日期格式转换
  11. python requests 乱码_解决使用requests中文乱码
  12. 数学建模技巧总结(一)
  13. 前度面试总结,被问的概率极大
  14. 千元机自拍新体验,vivo Z3是你会拍照的“男朋友”
  15. vue网易云歌单案例
  16. 学徒浅析Android——Android7.0(N)对于自定义证书和非CA机构证书的适配校验
  17. 基于HTML的环境网站设计 HTML+CSS环保网站项目实现 带设计说明psd
  18. 红色荧光染料AF 594活性酯,Alexa Fluor 594 NHS ester,CAS:295348-87-7
  19. 周涛教授:从窄门进走出宽路来!
  20. Vue3源码分析之打包原理

热门文章

  1. 用python制作勒索病毒_python生成的exe被360识别为勒索病毒原因及解决方法
  2. 【题解】「NOIP2016」蚯蚓
  3. cactiEZ 配置
  4. 高通MSM8937/ MSM8953/MSM8940/MSM8920/MSM8917启动流程简介
  5. ROS仿真环境安装与配置
  6. java开发微信公众号支付全流程
  7. qt -- QTableView
  8. 大数据学习笔记60:构建Spark机器学习系统
  9. 计算机技术专业求职简历,计算机技术专业求职简历模板
  10. 拼多多搜索API接口(关键词查询优惠券列表接口)