版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1334528
系统平台上打开pdf文件,chrome浏览器自动会打开这个附件。
那么,附件要用相对地址,绝对的pdf文件名称,可能给权限设计带来一点困扰,一般用/pdf?id=***来看附件,此时就必须用pdf.js这个插件来完成了。
找来找去还是这个http://www.cnblogs.com/kagome2014/p/kagome2014001.html靠谱,里面有打包好的。而git网站上原版却不怎么好运行起来。
http://blog.csdn.net/xiangcns/article/details/42089189这个似乎也不错。
看看我的把,添加了多页连续查看功能。其实就是用beego分页,不是一个pdf文件的多页,而是多个pdf文件连续看。
文件夹:
viewer.html
<!DOCTYPE html>
<!--
Copyright 2012 Mozilla Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Adobe CMap resources are covered by their own copyright and license:
http://sourceforge.net/adobe/cmap/wiki/License/
-->
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<title>PDF.js viewer</title>
<link rel="stylesheet" type="text/css" href="/static/font-awesome-4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="/static/pdfjs/viewer.css"/>
<script src="/static/pdfjs/compatibility.js"></script>
<!-- This snippet is used in production (included from viewer.html) -->
<link rel="resource" type="application/l10n" href="/static/pdfjs/locale.properties"/>
<script src="/static/pdfjs/l10n.js"></script>
<script src="/static/pdfjs/pdf.js"></script>
<script src="/static/pdfjs/debugger.js"></script>
<script type="text/javascript" src="/static/js/jquery-2.1.3.min.js"></script>
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>
<script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// $.ajax({
// type:"post",
// async: false,
// //ajax接收pdf数据流,注意dataType值的设置是否有错,如果不指定,jQuery将自动根据HTTP包MIME信息返回
// //responseXML或responseText . 回答问题1
// contentType:"application/pdf;charset=utf-8",
// url:"{% url netPan.File.views.browserFuf%}",
// data:{
// id: preFileId
// },
// success:function(data){
// var pdfAsDataUri = data;
// //如果引入了viewer.js , 处理方法
// var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
// DEFAULT_URL = pdfAsArray;
// // 只引入了pdf.js, 未引入viewer.js, 处理方法
// // var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
// // PDFJS.getDocument(pdfAsArray).then(); 自己写pdf的处理函数
// }
// });
DEFAULT_URL = {{.PdfLink}};//'/attachment/SL2017MeritEngineerCMS/20170902广州东莞压矿.pdf';
});
</script>
<!-- 这个要放后面 -->
<script src="/static/pdfjs/viewer.js"></script>
</head>
<body tabindex="1" class="loadingInProgress">
<div id="outerContainer">
<div id="sidebarContainer">
<div id="toolbarSidebar">
<div class="splitToolbarButton toggled">
<button id="viewThumbnail" class="toolbarButton group toggled" title="Show Thumbnails" tabindex="2" data-l10n-id="thumbs">
<span data-l10n-id="thumbs_label">Thumbnails</span>
</button>
<button id="viewOutline" class="toolbarButton group" title="Show Document Outline" tabindex="3" data-l10n-id="outline">
<span data-l10n-id="outline_label">Document Outline</span>
</button>
<button id="viewAttachments" class="toolbarButton group" title="Show Attachments" tabindex="4" data-l10n-id="attachments">
<span data-l10n-id="attachments_label">Attachments</span>
</button>
</div>
</div>
<div id="sidebarContent">
<div id="thumbnailView">
</div>
<div id="outlineView" class="hidden">
</div>
<div id="attachmentsView" class="hidden">
</div>
</div>
</div> <!-- sidebarContainer -->
<div id="mainContainer">
<div class="findbar hidden doorHanger hiddenSmallView" id="findbar">
<label for="findInput" class="toolbarLabel" data-l10n-id="find_label">Find:</label>
<input id="findInput" class="toolbarField" tabindex="91">
<div class="splitToolbarButton">
<button class="toolbarButton findPrevious" title="" id="findPrevious" tabindex="92" data-l10n-id="find_previous">
<span data-l10n-id="find_previous_label">Previous</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
<button class="toolbarButton findNext" title="" id="findNext" tabindex="93" data-l10n-id="find_next">
<span data-l10n-id="find_next_label">Next</span>
</button>
</div>
<input type="checkbox" id="findHighlightAll" class="toolbarField">
<label for="findHighlightAll" class="toolbarLabel" tabindex="94" data-l10n-id="find_highlight">Highlight all</label>
<input type="checkbox" id="findMatchCase" class="toolbarField">
<label for="findMatchCase" class="toolbarLabel" tabindex="95" data-l10n-id="find_match_case_label">Match case</label>
<span id="findMsg" class="toolbarLabel"></span>
</div> <!-- findbar -->
<div id="secondaryToolbar" class="secondaryToolbar hidden doorHangerRight">
<div id="secondaryToolbarButtonContainer">
<button id="secondaryPresentationMode" class="secondaryToolbarButton presentationMode visibleLargeView" title="Switch to Presentation Mode" tabindex="51" data-l10n-id="presentation_mode">
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
<button id="secondaryOpenFile" class="secondaryToolbarButton openFile visibleLargeView" title="Open File" tabindex="52" data-l10n-id="open_file">
<span data-l10n-id="open_file_label">Open</span>
</button>
<button id="secondaryPrint" class="secondaryToolbarButton print visibleMediumView" title="Print" tabindex="53" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>
<button id="secondaryDownload" class="secondaryToolbarButton download visibleMediumView" title="Download" tabindex="54" data-l10n-id="download">
<span data-l10n-id="download_label">Download</span>
</button>
<a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark visibleSmallView" title="Current view (copy or open in new window)" tabindex="55" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
<div class="horizontalToolbarSeparator visibleLargeView"></div>
<button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="56" data-l10n-id="first_page">
<span data-l10n-id="first_page_label">Go to First Page</span>
</button>
<button id="lastPage" class="secondaryToolbarButton lastPage" title="Go to Last Page" tabindex="57" data-l10n-id="last_page">
<span data-l10n-id="last_page_label">Go to Last Page</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="pageRotateCw" class="secondaryToolbarButton rotateCw" title="Rotate Clockwise" tabindex="58" data-l10n-id="page_rotate_cw">
<span data-l10n-id="page_rotate_cw_label">Rotate Clockwise</span>
</button>
<button id="pageRotateCcw" class="secondaryToolbarButton rotateCcw" title="Rotate Counterclockwise" tabindex="59" data-l10n-id="page_rotate_ccw">
<span data-l10n-id="page_rotate_ccw_label">Rotate Counterclockwise</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="toggleHandTool" class="secondaryToolbarButton handTool" title="Enable hand tool" tabindex="60" data-l10n-id="hand_tool_enable">
<span data-l10n-id="hand_tool_enable_label">Enable hand tool</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="61" data-l10n-id="document_properties">
<span data-l10n-id="document_properties_label">Document Properties…</span>
</button>
</div>
</div> <!-- secondaryToolbar -->
<div class="toolbar">
<div id="toolbarContainer">
<div id="toolbarViewer">
<div id="toolbarViewerLeft">
<button id="sidebarToggle" class="toolbarButton" title="Toggle Sidebar" tabindex="11" data-l10n-id="toggle_sidebar">
<span data-l10n-id="toggle_sidebar_label">Toggle Sidebar</span>
</button>
<div class="toolbarButtonSpacer"></div>
<button id="viewFind" class="toolbarButton group hiddenSmallView" title="Find in Document" tabindex="12" data-l10n-id="findbar">
<span data-l10n-id="findbar_label">Find</span>
</button>
<div class="splitToolbarButton">
<button class="toolbarButton pageUp" title="Previous Page" id="previous" tabindex="13" data-l10n-id="previous">
<span data-l10n-id="previous_label">Previous</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
<button class="toolbarButton pageDown" title="Next Page" id="next" tabindex="14" data-l10n-id="next">
<span data-l10n-id="next_label">Next</span>
</button>
</div>
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="15">
<span id="numPages" class="toolbarLabel"></span>
<!-- <div class="splitToolbarButtonSeparator"></div>
<button title="Previous Page" id="previous" tabindex="14" data-l10n-id="previous">
<span><i class="fa fa-arrow-left"></i></span>
</button>
<div class="splitToolbarButtonSeparator"></div>
<button title="Next Page" id="next" tabindex="14" data-l10n-id="next">
<span><i class="fa fa-arrow-right"></i></span>
</button> -->
</div>
<div id="toolbarViewerRight">
<button id="presentationMode" class="toolbarButton presentationMode hiddenLargeView" title="Switch to Presentation Mode" tabindex="31" data-l10n-id="presentation_mode">
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>
<button id="openFile" class="toolbarButton openFile hiddenLargeView" title="Open File" tabindex="32" data-l10n-id="open_file">
<span data-l10n-id="open_file_label">Open</span>
</button>
<button id="print" class="toolbarButton print hiddenMediumView" title="Print" tabindex="33" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>
<button id="download" class="toolbarButton download hiddenMediumView" title="Download" tabindex="34" data-l10n-id="download">
<span data-l10n-id="download_label">Download</span>
</button>
<a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="35" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
<div class="verticalToolbarSeparator hiddenSmallView"></div>
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="36" data-l10n-id="tools">
<span data-l10n-id="tools_label">Tools</span>
</button>
</div>
<div class="outerCenter">
<div class="innerCenter" id="toolbarViewerMiddle">
<div class="splitToolbarButton">
<button id="zoomOut" class="toolbarButton zoomOut" title="Zoom Out" tabindex="21" data-l10n-id="zoom_out">
<span data-l10n-id="zoom_out_label">Zoom Out</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
<button id="zoomIn" class="toolbarButton zoomIn" title="Zoom In" tabindex="22" data-l10n-id="zoom_in">
<span data-l10n-id="zoom_in_label">Zoom In</span>
</button>
</div>
<span id="scaleSelectContainer" class="dropdownToolbarButton">
<select id="scaleSelect" title="Zoom" tabindex="23" data-l10n-id="zoom">
<option id="pageAutoOption" title="" value="auto" selected="selected" data-l10n-id="page_scale_auto">Automatic Zoom</option>
<option id="pageActualOption" title="" value="page-actual" data-l10n-id="page_scale_actual">Actual Size</option>
<option id="pageFitOption" title="" value="page-fit" data-l10n-id="page_scale_fit">Fit Page</option>
<option id="pageWidthOption" title="" value="page-width" data-l10n-id="page_scale_width">Full Width</option>
<option id="customScaleOption" title="" value="custom"></option>
<option title="" value="0.5" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 50 }'>50%</option>
<option title="" value="0.75" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 75 }'>75%</option>
<option title="" value="1" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 100 }'>100%</option>
<option title="" value="1.25" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 125 }'>125%</option>
<option title="" value="1.5" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 150 }'>150%</option>
<option title="" value="2" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 200 }'>200%</option>
<option title="" value="3" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 300 }'>300%</option>
<option title="" value="4" data-l10n-id="page_scale_percent" data-l10n-args='{ "scale": 400 }'>400%</option>
</select>
</span>
</div>
</div>
</div>
<div id="loadingBar">
<div class="progress">
<div class="glimmer">
</div>
</div>
</div>
</div>
</div>
<menu type="context" id="viewerContextMenu">
<menuitem id="contextFirstPage" label="First Page"
data-l10n-id="first_page"></menuitem>
<menuitem id="contextLastPage" label="Last Page"
data-l10n-id="last_page"></menuitem>
<menuitem id="contextPageRotateCw" label="Rotate Clockwise"
data-l10n-id="page_rotate_cw"></menuitem>
<menuitem id="contextPageRotateCcw" label="Rotate Counter-Clockwise"
data-l10n-id="page_rotate_ccw"></menuitem>
</menu>
<div id="viewerContainer" tabindex="0">
<div id="viewer" class="pdfViewer"></div>
<div style="text-align:center;padding-left: 100px;margin-top: 0px;float: right;" class="pagination">
{{if .paginator}}
{{if gt .paginator.PageNums 1}}
<ul class="pagination pagination-sm">
{{if .paginator.HasPrev}}
<li>
<a href="{{.paginator.PageLinkFirst}}">首页</a>
</li>
<li>
<a href="{{.paginator.PageLinkPrev}}">上一页</a>
</li>
{{else}}
<li class="disabled">
<a>首页</a>
</li>
<li class="disabled">
<a>上一页</a>
</li>
{{end}}
{{range $index, $page := .paginator.Pages}}
<li{{if $.paginator.IsActive .}} class="active"{{end}}>
<a href="{{$.paginator.PageLink $page}}">{{$page}}</a>
</li>
{{end}}
{{if .paginator.HasNext}}
<li>
<a href="{{.paginator.PageLinkNext}}">下一页</a>
</li>
<li>
<a href="{{.paginator.PageLinkLast}}">末页</a>
</li>
{{else}}
<li class="disabled">
<a>下一页</a>
</li>
<li class="disabled">
<a>末页</a>
</li>
{{end}}
<li class="disabled">
<a>
共{{.paginator.Nums }}条数据 每页{{.paginator.PerPageNums}}条 当前{{.paginator.Page}}/{{.paginator.PageNums}}页
</a>
</li>
<li>
<input type="text" type="submit" id="p" name="p" placeholder="跳转页" style="width: 47px;height: 29px;border: 1px solid #dddddd;border-left: 0px;border-radius: 0px 4px 4px 0px;text-align: center;"/>
</li>
</ul>
{{end}}
{{end}}
</div>
</div>
<div id="errorWrapper" hidden='true'>
<div id="errorMessageLeft">
<span id="errorMessage"></span>
<button id="errorShowMore" data-l10n-id="error_more_info">
More Information
</button>
<button id="errorShowLess" data-l10n-id="error_less_info" hidden='true'>
Less Information
</button>
</div>
<div id="errorMessageRight">
<button id="errorClose" data-l10n-id="error_close">
Close
</button>
</div>
<div class="clearBoth"></div>
<textarea id="errorMoreInfo" hidden='true' readonly="readonly"></textarea>
</div>
</div> <!-- mainContainer -->
<div id="overlayContainer" class="hidden">
<div id="passwordOverlay" class="container hidden">
<div class="dialog">
<div class="row">
<p id="passwordText" data-l10n-id="password_label">Enter the password to open this PDF file:</p>
</div>
<div class="row">
<input type="password" id="password" class="toolbarField" />
</div>
<div class="buttonRow">
<button id="passwordCancel" class="overlayButton"><span data-l10n-id="password_cancel">Cancel</span></button>
<button id="passwordSubmit" class="overlayButton"><span data-l10n-id="password_ok">OK</span></button>
</div>
</div>
</div>
<div id="documentPropertiesOverlay" class="container hidden">
<div class="dialog">
<div class="row">
<span data-l10n-id="document_properties_file_name">File name:</span> <p id="fileNameField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_file_size">File size:</span> <p id="fileSizeField">-</p>
</div>
<div class="separator"></div>
<div class="row">
<span data-l10n-id="document_properties_title">Title:</span> <p id="titleField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_author">Author:</span> <p id="authorField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_subject">Subject:</span> <p id="subjectField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_keywords">Keywords:</span> <p id="keywordsField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_creation_date">Creation Date:</span> <p id="creationDateField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_modification_date">Modification Date:</span> <p id="modificationDateField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_creator">Creator:</span> <p id="creatorField">-</p>
</div>
<div class="separator"></div>
<div class="row">
<span data-l10n-id="document_properties_producer">PDF Producer:</span> <p id="producerField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_version">PDF Version:</span> <p id="versionField">-</p>
</div>
<div class="row">
<span data-l10n-id="document_properties_page_count">Page Count:</span> <p id="pageCountField">-</p>
</div>
<div class="buttonRow">
<button id="documentPropertiesClose" class="overlayButton"><span data-l10n-id="document_properties_close">Close</span></button>
</div>
</div>
</div>
</div> <!-- overlayContainer -->
</div> <!-- outerContainer -->
<div id="printContainer"></div>
<div id="mozPrintCallback-shim" hidden>
<style>
@media print {
#printContainer div {
page-break-after: always;
page-break-inside: avoid;
}
}
</style>
<style scoped>
#mozPrintCallback-shim {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 9999999;
display: block;
text-align: center;
background-color: rgba(0, 0, 0, 0.5);
}
#mozPrintCallback-shim[hidden] {
display: none;
}
@media print {
#mozPrintCallback-shim {
display: none;
}
}
#mozPrintCallback-shim .mozPrintCallback-dialog-box {
display: inline-block;
margin: -50px auto 0;
position: relative;
top: 45%;
left: 0;
min-width: 220px;
max-width: 400px;
padding: 9px;
border: 1px solid hsla(0, 0%, 0%, .5);
border-radius: 2px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
background-color: #474747;
color: hsl(0, 0%, 85%);
font-size: 16px;
line-height: 20px;
}
#mozPrintCallback-shim .progress-row {
clear: both;
padding: 1em 0;
}
#mozPrintCallback-shim progress {
width: 100%;
}
#mozPrintCallback-shim .relative-progress {
clear: both;
float: right;
}
#mozPrintCallback-shim .progress-actions {
clear: both;
}
</style>
<div class="mozPrintCallback-dialog-box">
<!-- TODO: Localise the following strings -->
Preparing document for printing...
<div class="progress-row">
<progress value="0" max="100"></progress>
<span class="relative-progress">0%</span>
</div>
<div class="progress-actions">
<input type="button" value="Cancel" class="mozPrintCallback-cancel">
</div>
</div>
</div>
</body>
</html>
控制器:
func (c *MainController) Pdf() {
v := c.GetSession("uname")
if v == nil {
route := c.Ctx.Request.URL.String()
c.Data["Url"] = route
c.Redirect("/roleerr?url="+route, 302)
return
}
//取得某个目录下所有pdf
var Url string
var pNum int64
id := c.Input().Get("id")
//id转成64为
idNum, err := strconv.ParseInt(id, 10, 64)
if err != nil {
beego.Error(err)
}
p := c.Input().Get("p")
var prods []*models.Product
var projid int64
if p == "" { //id是附件或成果id
attach, err := models.GetAttachbyId(idNum)
if err != nil {
beego.Error(err)
}
//由成果id(后台传过来的行id)取得成果——进行排序
prod, err := models.GetProd(attach.ProductId)
if err != nil {
beego.Error(err)
}
//由侧栏id取得所有成果和所有成果的附件pdf
prods, err = models.GetProducts(prod.ProjectId)
if err != nil {
beego.Error(err)
}
// beego.Info(prod.ProjectId)
//由proj id取得url
// Url, _, err = GetUrlPath(prod.ProjectId)
// if err != nil {
// beego.Error(err)
// }
// beego.Info(Url)
projid = prod.ProjectId
} else { //id是侧栏目录id
//由侧栏id取得所有成果和所有成果的附件pdf——进行排序
prods, err = models.GetProducts(idNum)
if err != nil {
beego.Error(err)
}
//由proj id取得url
Url, _, err = GetUrlPath(idNum)
if err != nil {
beego.Error(err)
}
// beego.Info(Url)
// projid = idNum
//id转成64为
pNum, err = strconv.ParseInt(p, 10, 64)
if err != nil {
beego.Error(err)
}
}
Attachments := make([]*models.Attachment, 0)
for _, v := range prods {
//根据成果id取得所有附件数量
Attachments1, err := models.GetAttachments(v.Id) //只返回Id?没意义,全部返回
if err != nil {
beego.Error(err)
}
for _, v := range Attachments1 {
if path.Ext(v.FileName) == ".pdf" || path.Ext(v.FileName) == ".PDF" {
Attachments = append(Attachments, Attachments1...)
}
}
}
count := len(Attachments)
count1 := strconv.Itoa(count)
count2, err := strconv.ParseInt(count1, 10, 64)
if err != nil {
beego.Error(err)
}
postsPerPage := 1
paginator := pagination.SetPaginator(c.Ctx, postsPerPage, count2)
c.Data["paginator"] = paginator
if p == "" {
var p1 string
for i, v := range Attachments {
if v.Id == idNum {
p1 = strconv.Itoa(i + 1)
// PdfLink = Url + "/" + v.FileName
break
}
}
c.Redirect("/pdf?p="+p1+"&id="+strconv.FormatInt(projid, 10), 302)
} else {
PdfLink := Url + "/" + Attachments[pNum-1].FileName
// beego.Info(PdfLink)
c.Data["PdfLink"] = PdfLink
c.TplName = "web/viewer.html"
}
}