1. 安裝插件
先安裝第一個html2canvas插件,作用是實現將html頁面轉換成圖片
安裝命令如下:
npm install --save html2canvas || npm install html2canvas
然后安裝第二個插件jspdf,作用是將圖片轉為pdf
安裝命令如下:
npm install jspdf --save || npm install jspdf
2. 導入html2canvas和jspdf插件到項目中
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
3. 定義一個div和需要生成pdf的頁面 (或者給需要到處的頁面元素最外層加id)
<div id="demo">
<div style={{marginTop:15}}>
<div>
此為到處的pdf文件
</div>
</div>
</div>
4. 定義一個觸發生成pdf文件的按鈕
<Button onClick={download}>生成報告</Button>
5. 實現download方法之一
download = () => {
const element = document.getElementById('demo'); // 這個dom元素是要導出的pdf的div容器
const w = element.offsetWidth; // 獲得該容器的寬
const h = element.offsetHeight; // 獲得該容器的高
const offsetTop = element.offsetTop; // 獲得該容器到文檔頂部的距離
const offsetLeft = element.offsetLeft; // 獲得該容器到文檔最左的距離
const canvas = document.creatElement("canvas");
let abs = 0;
const win_i = document.body.clientWidth; // 獲得當前可視窗口的寬度(不包含滾動條)
const win_o = window.innerWidth; // 獲得當前窗口的寬度(包含滾動條)
if(win_o > win_i){
abs = (win_o - win_i) / 2; // 獲得滾動條寬度的一半
}
canvas.width = w * 2; // 將畫布寬&&高放大兩倍
canvas.height = h * 2;
const context = canvas.getContext('2d');
context.scale(2, 2);
context.translate(-offsetLeft - abs, -offsetTop);
// 這里默認橫向沒有滾動條的情況,因為offset.left(),有無滾動條的時候存在差值,因此translate的時候,要把這個差值去掉
html2canvas(element, {
allowTaint: true,
scale: 2 // 提升畫面質量,但是會增加文件大小
}).then( canvas => {
const contentWidth = canvas.width;
const contentHeight = canvas.height;
// 一頁pdf顯示html頁面生成的canvas高度
const pageHeight = contentWidth / 592.28 * 841.89;
// 未生成pdf的html頁面高度
const leftHeight = contentHeight;
// 頁面偏移
const position = 0;
// a4紙的尺寸[595.28,841.89],html頁面生成的canvas在pdf中圖片的寬高
const imgWidth = 595.28;
const imgHeight = 592.28 / contentWidth * contentHeight;
const pageDate = canvas.toDataURL('image/jpeg', 1.0);
const pdf = new jsPDF('', 'pt', 'a4');
// 有兩個高度需要區分,一個是html頁面的實際高度,和生成pdf的頁面的高度(841.89)
// 當內容未超過pdf一頁顯示的范圍,無需分頁
if(leftHeight < pageHeight) {
pdf.addImage(pageDate,'JPEG', 0, position, imgWidth, imgHeight);
}else { // 分頁
while (leftHeight > 0){
pdf.addImage(pageDate, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight;
position -= 841.89;
// 避免添加空白頁
if(leftHeight > 0){
pdf.addPage()
}
}
}
pdf.save('你的名字.pdf');
})
}
方法二:
download = () => {
const element = document.getElementById('demo');
const imgHeight = element.clientHeight;
const imgWidth = element.clientWidth;
const scale = 3;
html2canvas(element, {
letterRendering: true,
allowTaint: true,
taintTest: false,
height: imgHeight,
// 為了使橫向滾動條的內容全部展示,這里必須指定
width: imgWidth,
backgroundColor: '#fff',
scale: scale, // 提升畫面質量,但是會增加文件大小,
onclone: (element) => {
const inputs = element.getElementsByTagName("input")
let inputList = Array.prototype.slice.call(inputs);
inputList.map((item)=>{
if(item.placeholder){
item.removeAttribute("placeholder")
}
})
let selectHolder = detail.querySelectorAll(".ant-select-selection-placeholder")
let selectHolderList = Array.prototype.slice.call(selectHolder)
selectHolderList.map((item)=>{
item.style.display = "none"
})
// detail.getElementById("campaignInfo_targetGroupDescription").removeAttribute("placeholder")
// onclone logic to resize div
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
},500)
})
}
}).then((canvas) => {
const pageData = canvas.toDataURL('image/jpeg', 1);
// 設置pdf的尺寸,pdf要使用pt單位 已知 1pt/1px = 0.75 pt = (px/scale)* 0.75
// scale為上面的scale 縮放了scale倍, 60為pdf四周留白
let pdfX = (imgWidth + 60) / scale * 0.75
let pdfY = (imgHeight + 60) / scale * 0.75
let imgX = (imgWidth / scale * 0.75)
let imgY = (imgHeight / scale * 0.75); //內容圖片這里不需要留白的距離
// pdfX,pdfY為pdf的大小,imgX,imgY為內容圖片的大小
let PDF = new jsPDF('', 'pt', [pdfX, pdfY])
// 7.5 為坐標,讓img在pdf中水平垂直居中,四周留白均勻
PDF.addImage(pageData, 'JPEG', 7.5, 7.5, imgX, imgY);
//獲取當前時間戳
let timestmp = new Date().getTime()
PDF.save(`cmt_campaign_basic_info_${lib.dataFormat(timestmp)}.pdf`);
this.campaignDetailStore.pdfLoadingVisible = false
// this.setState({
// pdfimg:pageData
// })
}).catch(() => {
this.campaignDetailStore.pdfLoadingVisible = false
// this.setState({ exportPDF: false });
});
};
