效果預(yù)覽
使用第三方插件
安裝依賴插件
npm i vue-pdf --save
npm i pdf-lib --save
npm install --save @pdf-lib/fontkit //為 pdf-lib 加載自定義字體的工具
import 導(dǎo)入依賴
import pdf from "vue-pdf";
import { degrees, PDFDocument, rgb, StandardFonts } from "pdf-lib";
import fontkit from "@pdf-lib/fontkit";
預(yù)覽添加水印的pdf
setWatermarkContent() {
let ele = document.createElement("canvas");
ele.width = 250;
ele.height = 200;
let objmsg = {
canvas: ele,
fontText: "張三-2023-01-01",
fontSize: 20,
fontFamily: "microsoft yahei",
fontcolor: "#dadbdc", //字體顏色 默認 #dadbdc
rotate: 25, //旋轉(zhuǎn)角度 數(shù)字類型
textAlign: "left", //水印文字居中方式:left center right 默認 left
};
this.createWaterMark(objmsg);
this.drawWaterMark(ele);
},
// 創(chuàng)建canvas水印圖片
createWaterMark({ canvas, fontText, fontFamily = "microsoft yahei", fontSize = 30, fontcolor = "#dadbdc", rotate = 30, textAlign = "left" }) {
let ctx = canvas.getContext("2d");
ctx.font = `${fontSize}px ${fontFamily}`;
ctx.rotate((-rotate * Math.PI) / 180);
ctx.fillStyle = fontcolor;
ctx.textAlign = textAlign;
ctx.textBaseline = "Middle";
ctx.fillText(fontText, canvas.width / 6, canvas.height / 2);
},
// 給pdf增加水印遮罩層
drawWaterMark(ele) {
let div = document.createElement("div");
div.style.pointerEvents = "none";
div.style.top = "0";
div.style.left = "0px";
div.style.position = "absolute";
div.style.background = "url(" + ele.toDataURL("image/png") + ") left top repeat";
let width = document.getElementById("pdfBox").clientWidth || 700;
let height = document.getElementById("pdfBox").clientHeight || 700;
div.style.width = width + "px";
div.style.height = height + "px";
document.getElementById("myIframe").appendChild(div);
},
下載添加水印的pdf
原理就是給顯示pdf 的容器增加一層水印遮罩層
// 處理PDF
async downFile() {
/*2.獲取pdf文件的arrarybuffer文件流
可請求后臺接口返回的base64文件流,然后轉(zhuǎn)成arrayBuffer類型
可訪問前端項目中的本地文件,不能直接訪問服務(wù)器鏈接文件,會有跨域問題*/
try {
// 1.通過url獲取pdf文件的arrarybuffer文件流
const existingPdfBytes = await fetch(this.fileUrl).then((res) => res.arrayBuffer());
// 2.將arraybuffer數(shù)據(jù)轉(zhuǎn)成pdf文檔
const pdfDoc = await PDFDocument.load(existingPdfBytes);
// 3.1 內(nèi)置字體(不支持中文), 如果水印中不包含中文可直接用內(nèi)置字體(不支持中文)
// const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);
// 3.2 自定義字體,如不需要使用自定義字體可以將這一段全部注釋掉,也不用下載自定義字體文件和自定義字體工具fontkit
// 將自己下載好的.ttf文件放置項目中,然后訪問文件路徑(不支持訪問本地文件)
const fontBytes = await fetch("/fonts/SourceHanSansCN-Normal.ttf").then((res) => res.arrayBuffer());
pdfDoc.registerFontkit(fontkit); // 自定義字體掛載、fontkit為自定義字體注冊工具
const fontkitFile = await pdfDoc.embedFont(fontBytes);
// 4. 為每頁pdf添加文字水印
const pages = pdfDoc.getPages();
for (let i = 0; i < pages.length; i++) {
const noPage = pages[i];
const { width, height } = noPage.getSize();
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 3; j++) {
noPage.drawText("張三-2023-01-01", {
x: 230 * j,
y: (height / 4) * i,
size: 20,
font: fontkitFile, //字體(內(nèi)置/自定義)
color: rgb(0.46, 0.53, 0.6),
rotate: degrees(45),
opacity: 0.3,
});
}
}
}
//5. 保存pdf文件的unit64Arrary文件流
const pdfBytes = await pdfDoc.save();
this.saveByteArray(this.waterFile.fileName + ".pdf", pdfBytes);
} catch (error) {
this.$message.warning("文件下載失??!");
}
},
// 下載文件
saveByteArray(reportName, byte) {
var blob = new Blob([byte], { type: "application/pdf" });
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
},
預(yù)覽及下載總結(jié)
下載:文章來源:http://www.zghlxwxcb.cn/news/detail-819829.html
- 通過url獲取pdf文件的arrarybuffer文件流
- 將arraybuffer數(shù)據(jù)轉(zhuǎn)成pdf文檔
- 添加水印字體(內(nèi)置/自定義)
- 為每頁pdf添加文字水印
- 保存pdf文件的unit64Arrary文件流
預(yù)覽:文章來源地址http://www.zghlxwxcb.cn/news/detail-819829.html
- 創(chuàng)建canvas容器(用于顯示水印文字)
- 創(chuàng)建水印canvas
- 將水印canvas遮罩層定位到pdf容器中
完整代碼
<template>
<div>
<div class="content">
<div id="myIframe" style="max-width: 700px; min-height: 550px; position: relative; margin: 0 auto">
<pdf id="pdfBox" :page="pageNum" :src="fileUrl" @progress="loadedRatio = $event" @num-pages="totalPages = $event"></pdf>
</div>
<el-button v-if="false" type="primary" @click="downFile" plain style="width: 300px">保存并下載pdf</el-button>
</div>
<span slot="footer" class="dialog-footer">
<div class="btnGroup" v-if="totalPages">
<div class="pageNum">{{ pageNum }} / {{ totalPages }}</div>
<el-button-group>
<el-button round plain type="primary" icon="el-icon-arrow-left" size="mini" @click="prePage">上一頁</el-button>
<el-button round plain type="primary" size="mini" @click="nextPage">下一頁<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>
</div>
</span>
</div>
</template>
<script>
/* npm i vue-pdf --save
npm install --save @pdf-lib/fontkit
npm i pdf-lib --save
*/
import pdf from "vue-pdf";
import { degrees, PDFDocument, rgb, StandardFonts } from "pdf-lib";
import fontkit from "@pdf-lib/fontkit"; //為 pdf-lib 加載自定義字體的工具
export default {
components: {
pdf,
},
data() {
return {
pageNum: 1, //顯示第一頁
loadedRatio: 0, // 當前頁面的加載進度,范圍是0-1 ,等于1的時候代表當前頁已經(jīng)完全加載完成了
totalPages: 0, //pdf總頁數(shù)
fileUrl:"XXXXX.pdf",
};
},
mounted() {
this.getPageNum();
},
methods: {
// 獲取PDF總頁數(shù)
getPageNum() {
let loadingTask = pdf.createLoadingTask(this.fileUrl);
loadingTask.promise
.then((pdf) => {
this.totalPages = pdf.numPages;
this.$nextTick(() => {
this.setWatermarkContent();
});
})
.catch((err) => {
this.$message.warning("pdf加載失敗");
});
},
// 上一頁
prePage() {
let page = this.pageNum;
page = page > 1 ? page - 1 : this.totalPages;
this.pageNum = page;
window.scrollTo(0, 0);
},
// 下一頁
nextPage() {
let page = this.pageNum;
page = page < this.totalPages ? page + 1 : 1;
this.pageNum = page;
window.scrollTo(0, 0);
},
setWatermarkContent() {
// 1.創(chuàng)建canvas容器(用于顯示水印文字)
let ele = document.createElement("canvas");
ele.width = 250;
ele.height = 200;
let objmsg = {
canvas: ele,
fontText: "張三-2023-01-01", // String
fontSize: 20,
fontFamily: "microsoft yahei",
fontcolor: "#dadbdc", //字體顏色 默認 #dadbdc
rotate: 25, //旋轉(zhuǎn)角度 數(shù)字類型
textAlign: "left", //水印文字居中方式:left center right 默認 left
};
// 2.創(chuàng)建水印canvas
this.createWaterMark(objmsg);
// 2.將水印canvas遮罩層定位到pdf容器中
this.drawWaterMark(ele);
},
// 創(chuàng)建canvas水印圖片
createWaterMark({ canvas, fontText, fontFamily = "microsoft yahei", fontSize = 30, fontcolor = "#dadbdc", rotate = 30, textAlign = "left" }) {
let ctx = canvas.getContext("2d");
ctx.font = `${fontSize}px ${fontFamily}`;
ctx.rotate((-rotate * Math.PI) / 180);
ctx.fillStyle = fontcolor;
ctx.textAlign = textAlign;
ctx.textBaseline = "Middle";
ctx.fillText(fontText, canvas.width / 6, canvas.height / 2);
},
// 給pdf增加水印遮罩層
drawWaterMark(ele) {
let div = document.createElement("div");
div.style.pointerEvents = "none";
div.style.top = "0";
div.style.left = "0px";
div.style.position = "absolute";
div.style.background = "url(" + ele.toDataURL("image/png") + ") left top repeat";
let width = document.getElementById("pdfBox").clientWidth || 700;
let height = document.getElementById("pdfBox").clientHeight || 700;
div.style.width = width + "px";
div.style.height = height + "px";
document.getElementById("myIframe").appendChild(div);
},
// PDF 下載
async downFile() {
/*2.獲取pdf文件的arrarybuffer文件流
可請求后臺接口返回的base64文件流,然后轉(zhuǎn)成arrayBuffer類型
可訪問前端項目中的本地文件,不能直接訪問服務(wù)器鏈接文件,會有跨域問題*/
try {
// 1.通過url獲取pdf文件的arrarybuffer文件流
const existingPdfBytes = await fetch(this.fileUrl).then((res) => res.arrayBuffer());
// 2.將arraybuffer數(shù)據(jù)轉(zhuǎn)成pdf文檔
const pdfDoc = await PDFDocument.load(existingPdfBytes);
// 3.1 內(nèi)置字體(不支持中文), 如果水印中不包含中文可直接用內(nèi)置字體(不支持中文)
// const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);
// 3.2 自定義字體,如不需要使用自定義字體可以將這一段全部注釋掉,也不用下載自定義字體文件和自定義字體工具fontkit
// 將自己下載好的.ttf文件放置項目中,然后訪問文件路徑(不支持訪問本地文件)
const fontBytes = await fetch("/fonts/SourceHanSansCN-Normal.ttf").then((res) => res.arrayBuffer());
pdfDoc.registerFontkit(fontkit); // 自定義字體掛載、fontkit為自定義字體注冊工具
const fontkitFile = await pdfDoc.embedFont(fontBytes);
// 4. 為每頁pdf添加文字水印
const pages = pdfDoc.getPages();
for (let i = 0; i < pages.length; i++) {
const noPage = pages[i];
const { width, height } = noPage.getSize();
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 3; j++) {
noPage.drawText('張三-2023-01-01', {
x: 230 * j,
y: (height / 4) * i,
size: 20,
font: fontkitFile, //字體(內(nèi)置/自定義)
color: rgb(0.46, 0.53, 0.6),
rotate: degrees(45),
opacity: 0.3,
});
}
}
}
//5. 保存pdf文件的unit64Arrary文件流
const pdfBytes = await pdfDoc.save();
this.saveByteArray( "水印PDF.pdf", pdfBytes);
} catch (error) {
this.$message.warning("文件下載失??!");
}
},
// 下載文件
saveByteArray(fileName, byte) {
var blob = new Blob([byte], { type: "application/pdf" });
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
},
},
};
</script>
到了這里,關(guān)于前端使用vue-pdf、pdf-lib、canvas 給PDF文件添加水印,并預(yù)覽與下載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!