Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
、PDF.JS
用于在瀏覽器中直接顯示 PDF 文檔,它是免費(fèi)開源的 JavaScript,由Mozilla維護(hù)。顯示方式:
> 方法1:直接獲到pdfviewer,復(fù)制到文件夾中,在要顯示pdf文件網(wǎng)頁(yè)內(nèi)用iframe嵌入即可。
pdfviewer
嵌入iframe:“pdfviewer/web/viewer.html?file=pdf文件名.pdf”。
iframe嵌入pdf文件名
> 方法2:也是iframe嵌入pdfview,與方法1區(qū)別是,方法1直接暴露pdf文件名,可以間接下載pdf文件,方法2用Blob(Binary Large Object)嵌入。
步驟如下:后臺(tái)程序把pdf文件內(nèi)容轉(zhuǎn)換成base64編碼傳到前端網(wǎng)頁(yè);
轉(zhuǎn)base64編碼
前端界面讀取base64編碼內(nèi)容;
讀取base64
base64轉(zhuǎn)二進(jìn)制;
轉(zhuǎn)二進(jìn)制
iframe嵌入,src為blob地址;
iframe嵌入blob地址
> 方法3:引用pdf.js和pdf.worker.js,操作pdf對(duì)象var loadingTask=PDFJS.getDocument(path).promise;
pdf對(duì)象
二、FlexPaper
FlexPaper基于flash對(duì)象,有些瀏覽器不再支持flash對(duì)象,故FlexPaper對(duì)有些瀏覽器在線顯示文檔不工作。FlexPaper是一個(gè)開源輕量級(jí)的文檔瀏覽組件,目的是在網(wǎng)頁(yè)上,基于Flash的應(yīng)用程序能在瀏覽器中顯示PDF文件。FlexPaper項(xiàng)目同時(shí)提供了Flex庫(kù)和獨(dú)立的Flash版本。
步驟如下:
1、將需要展現(xiàn)的文件如word、ppt轉(zhuǎn)換成pdf;
2、SWFTools工具包中的pdf2swf將pdf格式文件轉(zhuǎn)換成swf格式文件;
pdf轉(zhuǎn)swf
3、在前端網(wǎng)頁(yè)中引用flexpaper_flash.js;
flexpaper_flash.js
4、前端網(wǎng)頁(yè)用FlexPaperViewer顯示swf文件,其中SwfFile就是生成的flash文件格式swf文件;
方法1,直接寫JS
方法2:用swfobject嵌入
了在你的HMTL5 網(wǎng)站上查看PDF 文件,你要將它們嵌入到HTML5 PDF 查看器中。像Chrome這樣的瀏覽器已經(jīng)有一個(gè)插件可以做到這一點(diǎn),因此,你的PDF 文件將正確顯示給使用Chrome瀏覽器訪問(wèn)你網(wǎng)站的人。不過(guò),還有使用插件的替代方法。例如,AdobeInDesign 將幫助你構(gòu)建交互式pdf。還有其他提示和技巧可用于呈現(xiàn)你的PDF文件,以便每個(gè)人都可以查看它們。想了解更多的查看方法,可以考慮報(bào)個(gè)HMTL5培訓(xùn)班,有專業(yè)導(dǎo)師面授教學(xué),課程緊隨企業(yè)需求,培養(yǎng)全棧開發(fā)人才。
獲取HTML5 PDF 查看器
網(wǎng)絡(luò)上有許多HTML5 PDF 查看器。例如,這些網(wǎng)站都可以提供在你的網(wǎng)站上使用的PDF查看器,并且所有瀏覽器都應(yīng)該能夠查看你的文件:IDR解決方案、PDF項(xiàng)目、軟紙項(xiàng)目、非常PDF。
你上傳文件并選擇HTML5,然后輸出你需要嵌入網(wǎng)頁(yè)的代碼。當(dāng)有人訪問(wèn)你的網(wǎng)頁(yè)時(shí),他們將能夠在查看器中查看你的PDF 文件,而不是彈出鏈接。這些大多數(shù)PDF查看器網(wǎng)站也有出售軟件,這樣你就可以在計(jì)算機(jī)上擁有它的副本,而不必去他們的網(wǎng)站在線使用它。擁有該軟件的副本可以保護(hù)你的PDF副本(如果它受版權(quán)保護(hù)),并且通常還會(huì)為你提供更好的軟件版本。如果你想從事HTML5開發(fā),又不知道從何學(xué)起,HMTL5培訓(xùn)學(xué)習(xí)就是一個(gè)不錯(cuò)的選擇,不只是學(xué)習(xí)理論知識(shí),還有實(shí)踐項(xiàng)目的操作訓(xùn)練,讓學(xué)生學(xué)以致用,提升學(xué)員全局性思維和全棧技術(shù)能力。
將PDF 文件轉(zhuǎn)換為HTML5
你可以將PDF 文件轉(zhuǎn)換為HTML5,以便每個(gè)人都能很好地查看你的文件。這樣,你就不必?fù)?dān)心別人看不到文件,因?yàn)樗麄兊臑g覽器沒有插件來(lái)查看它,或者你的插件不適用于他們的計(jì)算機(jī)或?yàn)g覽器。所以有人會(huì)看不到你的文件。
HTML5– 新方式
除了大多數(shù)設(shè)計(jì)師、Apple和Adobe 使用HTML5來(lái)創(chuàng)建他們的東西,使用HTML5 的另一個(gè)好處是新改進(jìn)的頁(yè)面標(biāo)題。你可以使用一些有意義的東西,如
移動(dòng)設(shè)備是在網(wǎng)站上使用HTML5的一個(gè)重要原因。現(xiàn)在每個(gè)人都用手機(jī),會(huì)產(chǎn)生巨大的訪問(wèn)量,如果你的網(wǎng)站要接觸到這些移動(dòng)用戶,那么你就要使用HTML5編寫內(nèi)容。
有很多方法可以在你的網(wǎng)站上完成HTML5 PDF 查看器。你可以嵌入代碼,也可以使用插件。還有一些網(wǎng)站提供免費(fèi)的在線代碼生成器,為你編寫代碼,這樣你的PDF文件就會(huì)像雜志一樣顯示,用戶可以直接在你的網(wǎng)站上閱讀。如果你想了解有關(guān)HTML5的更多信息,可以參加HTML5培訓(xùn)班學(xué)習(xí),能夠快速掌握更系統(tǒng)全面的HTML5知識(shí),讓你在短時(shí)間內(nèi)學(xué)有所成。
了解更多
何保持頁(yè)面樣式基本不變的前提下將HTML頁(yè)面導(dǎo)出為PDF,下面提供一些示例代碼,純屬個(gè)人原創(chuàng),如對(duì)你有幫助請(qǐng)記得加關(guān)注、加收藏、點(diǎn)贊、轉(zhuǎn)發(fā)、分享~謝謝~~
<div>
<!-- 要打印的內(nèi)容區(qū) -->
<div ref="contentRef">
<div class="print-item print-out-flow">這是脫離文檔流的內(nèi)容區(qū)域</div>
<div class="print-item">這是一行內(nèi)容,也是最小葉子元素內(nèi)容</div>
</div>
<!-- 打印內(nèi)容容器 -->
<div ref="printContainerRef" class="print-container"></div>
</div>
/**
* 1.使用一個(gè)隱藏div裝載有滾動(dòng)條的div.innerHTML
* 2.隱藏div使用position: absolute, z-index: -999, left: -9999px, width: 900px 控制讓用戶無(wú)感知
* 3.根據(jù)需要覆寫隱藏div內(nèi)html樣式(例如textarea多行顯示有問(wèn)題, 可以新增一個(gè)隱藏的div
* 包裹textarea的綁定值, 然后在打印樣式中覆寫樣式, 隱藏textarea并顯示對(duì)應(yīng)div)
*/
handleExport() {
// 下面是VUE組件內(nèi)獲取DOM元素代碼,將內(nèi)容放置到打印區(qū)(定義的隱藏DIV)中
const contentRef=this.$refs.contentRef as HTMLElement;
const printContainerRef=this.$refs.printContainerRef as HTMLElement;
// 打印區(qū)的需額外處理絕對(duì)定位值, 調(diào)整使得第一個(gè)元素的.top值為0, 以便于頁(yè)面計(jì)算
printContainerRef.innerHTML=contentRef.innerHTML;
// 所有葉子div元素加上 print-item 樣式名, 脫離文檔流的額外添加 print-out-flow
handlePrintItem(printContainerRef); // 解決多頁(yè)內(nèi)容可能被切割問(wèn)題
html2canvas(printContainerRef, {allowTaint: false, useCORS: true}).then((canvas: any)=> {
const contentHeight=canvas.height;
const contentWidth=canvas.width;
// pdf每頁(yè)顯示的內(nèi)容高度
const pageHeight=contentWidth / 595.28 * 841.89;
// 未生成pdf的頁(yè)面高度
let offsetHeight=contentHeight;
// 頁(yè)面偏移值
let position=0;
// a4紙的尺寸[595.28, 841.89], canvas圖片按a4紙大小縮放后的寬高
const imgWidth=595.28;
const imgHeight=595.28 / contentWidth * contentHeight;
const dataURL=canvas.toDataURL('image/jpeg', 1.0);
const doc=new jsPDF('p', 'pt', 'a4');
if (offsetHeight < pageHeight) {
doc.addImage(dataURL, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
while (offsetHeight > 0) {
doc.addImage(dataURL, 'JPEG', 0, position, imgWidth, imgHeight);
offsetHeight -=pageHeight;
position -=841.89;
if (offsetHeight > 0) {
doc.addPage();
}
}
}
doc.save(this.generateReportFileName());
printContainerRef.innerHTML='';
});
}
上干貨代碼:上面分頁(yè)導(dǎo)出PDF可能網(wǎng)上能看到類型代碼,但絕對(duì)找不到下面的代碼,純手搓解決分頁(yè)元素被切開問(wèn)題(思路:獲取自身定位,如自己剛好在被分頁(yè)處,則加上一定的margin-top值將內(nèi)容向下移)
/**
* 處理打印元素項(xiàng), 修復(fù)分頁(yè)后被切割的元素
* @param printContainerRef 打印內(nèi)容div容器
* @param itemClassName 打印最小元素標(biāo)識(shí)類名
* @param outFlowClassName 脫離文檔流的元素標(biāo)識(shí)類名
*/
export function handlePrintItem(
printContainerRef: HTMLElement,
itemClassName: string='print-item',
outFlowClassName: string='print-out-flow'
): void {
const rootClientRect=printContainerRef.getBoundingClientRect();
// 初始化頁(yè)面相關(guān)數(shù)據(jù)
const totalHeight=rootClientRect.height; // 內(nèi)容總高度
const a4PageHeight=(printContainerRef.clientWidth / 595.28) * 841.89; // a4紙高度
let pageNum=Math.ceil(totalHeight / a4PageHeight); // 總頁(yè)數(shù)
let addPageHeight=0; // 修正被分割元素而增加的頁(yè)面高度總和
let currentPage=1; // 當(dāng)前正在處理切割的頁(yè)面
const splitItemObj: { [key: number]: HTMLElement[] }={}; // 內(nèi)容中各頁(yè)被切割元素存儲(chǔ)對(duì)象
const printItemNodes: NodeListOf<HTMLElement>=printContainerRef.querySelectorAll(`.${itemClassName}`);
for (let item of printItemNodes) {
// 如果當(dāng)前頁(yè)已經(jīng)是最后一頁(yè), 則中斷判斷
if (currentPage >=pageNum) {
break;
}
// 獲取元素絕對(duì)定位數(shù)據(jù)
const clientRect=item.getBoundingClientRect();
let top=clientRect.top;
const selfHeight=clientRect.height;
// 如果當(dāng)前元素距離頂部高度大于當(dāng)前頁(yè)面頁(yè)腳高度, 則開始判斷下一頁(yè)頁(yè)腳被切割元素
if (top > currentPage * a4PageHeight) {
// 換頁(yè)前修正上一頁(yè)被切割元素
addPageHeight +=fixSplitItems(currentPage, a4PageHeight, splitItemObj[currentPage], outFlowClassName);
pageNum=Math.ceil((totalHeight + addPageHeight) / a4PageHeight);
top=item.getBoundingClientRect().top;
currentPage++;
}
// 如果元素剛好處于兩頁(yè)之間, 則記錄該元素
if (top > (currentPage - 1) * a4PageHeight && top < currentPage * a4PageHeight && top + selfHeight > currentPage * a4PageHeight) {
if (!splitItemObj[currentPage]) {
splitItemObj[currentPage]=[];
}
splitItemObj[currentPage].unshift(item);
// 如果當(dāng)前元素是最后一個(gè)元素, 則直接處理切割元素, 否則交由處理下一頁(yè)元素時(shí)再處理切割
if (item===printItemNodes[printItemNodes.length - 1]) {
fixSplitItems(currentPage, a4PageHeight, splitItemObj[currentPage], outFlowClassName);
}
}
}
}
/**
* 修復(fù)當(dāng)前頁(yè)所有被切割元素
* @param currentPage 當(dāng)前頁(yè)
* @param pageHeight 每頁(yè)高度
* @param splitElementItems 當(dāng)前被切割元素?cái)?shù)組
* @param outFlowClassName 脫離文檔流的樣式類名
*/
function fixSplitItems(
currentPage: number,
pageHeight: number,
splitElementItems: HTMLElement[],
outFlowClassName: string
): number {
if (!splitElementItems || !splitElementItems.length) {
return 0;
}
const yMargin=5; // y方向距離頁(yè)眉的距離
const splitItemsMinTop=getSplitItemsMinTop(splitElementItems);
if (!splitItemsMinTop) {
return 0;
}
let fixHeight=currentPage * pageHeight - splitItemsMinTop + yMargin;
const outFlowElement=splitElementItems.find((item)=> item.classList.contains(outFlowClassName));
if (outFlowElement && outFlowElement.parentElement) {
const parentPreviousElement=outFlowElement.parentElement.previousElementSibling as HTMLElement;
fixHeight +=getMarinTopNum(parentPreviousElement, outFlowElement.parentElement);
outFlowElement.parentElement.style.marginTop=`${fixHeight}px`;
return fixHeight;
}
splitElementItems.forEach((splitElement)=> {
splitElement.style.marginTop=`${fixHeight}px`;
});
return fixHeight;
}
/**
* 獲取被切割元素?cái)?shù)組中最小高度值(如一行有多個(gè)元素被切割,則選出距離頂部最小的高度值)
* @param splitElementItems 當(dāng)前被切割元素?cái)?shù)組
*/
function getSplitItemsMinTop(
splitElementItems: HTMLElement[]
): number | undefined {
// 獲取元素中最小top值作為基準(zhǔn)進(jìn)行修正
let minTop: number | undefined;
let minElement: HTMLElement | undefined;
splitElementItems.forEach((splitElement)=> {
let top=splitElement.getBoundingClientRect().top;
if (minTop) {
minTop=top < minTop ? top : minTop;
minElement=top < minTop ? splitElement : minElement;
} else {
minTop=top;
minElement=splitElement;
}
});
// 修正當(dāng)前節(jié)點(diǎn)及其前面同層級(jí)節(jié)點(diǎn)的margin值
if (minTop && minElement) {
const previousElement=splitElementItems[splitElementItems.length - 1].previousElementSibling as HTMLElement;
minTop -=getMarinTopNum(previousElement, minElement);
}
return minTop;
}
/**
* 通過(guò)前一個(gè)兄弟元素和元素自身的位置確認(rèn)一個(gè)距離頂部高度修正值
* @param previousElement 前一個(gè)兄弟元素
* @param curElement 當(dāng)前元素
*/
function getMarinTopNum(previousElement: HTMLElement, curElement: HTMLElement): number {
let preMarginNum=0;
let curMarginNum=0;
if (previousElement) {
// 獲取外聯(lián)樣式需要getComputedStyle(), 直接.style時(shí)對(duì)象的值都為空
const previousMarginBottom=window.getComputedStyle(previousElement).marginBottom;
preMarginNum=previousMarginBottom ? Number(previousMarginBottom.replace('px', '')) : 0;
}
const marginTop=window.getComputedStyle(curElement).marginTop;
curMarginNum=marginTop ? Number(marginTop.replace('px', '')) : 0;
return preMarginNum > curMarginNum ? preMarginNum : curMarginNum;
}
以上純?cè)瓌?chuàng)!歡迎加關(guān)注、加收藏、點(diǎn)贊、轉(zhuǎn)發(fā)、分享(代碼閑聊站)~
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。