|
|
@ -28,6 +28,8 @@ import { TextLayerBuilder, EventBus } from 'pdfdist-mergeofd/web/pdf_viewer' |
|
|
|
import 'pdfdist-mergeofd/web/pdf_viewer.css' |
|
|
|
PDFJS.GlobalWorkerOptions.workerSrc = require('pdfdist-mergeofd/build/pdf.worker.entry.js') |
|
|
|
import { saveByteArray } from '@/utils/index' |
|
|
|
import { getInitWatermark } from '@/api/system/waterMask' |
|
|
|
import { FetchGetFilingsealFormat, FetchGetFilingsealFormatDtails } from '@/api/system/category/category' |
|
|
|
import fontkit from '@pdf-lib/fontkit' |
|
|
|
|
|
|
|
export default { |
|
|
@ -46,10 +48,21 @@ export default { |
|
|
|
arr: [ |
|
|
|
{ zongshu: '001', yilei: '2015', erlei: '2' }, |
|
|
|
{ zongshu: '', yilei: '长期', erlei: '1' } |
|
|
|
] |
|
|
|
], |
|
|
|
watermarkInfo: null, |
|
|
|
initColor: null, |
|
|
|
fileParentInfo: null, |
|
|
|
selectedCategory:null, |
|
|
|
formatData:[] |
|
|
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
if (localStorage.getItem('fileParentInfo')) { |
|
|
|
this.fileParentInfo = JSON.parse(localStorage.getItem('fileParentInfo')) |
|
|
|
} |
|
|
|
if (localStorage.getItem('currentArchivesKey')) { |
|
|
|
this.selectedCategory = JSON.parse(localStorage.getItem('currentArchivesKey')) |
|
|
|
} |
|
|
|
this.loadFile() |
|
|
|
}, |
|
|
|
methods: { |
|
|
@ -94,94 +107,117 @@ export default { |
|
|
|
pdfDoc.registerFontkit(fontkit) // 自定义字体挂载、fontkit为自定义字体注册工具 |
|
|
|
const customFont = await pdfDoc.embedFont(fontBytes) |
|
|
|
const pages = pdfDoc.getPages() |
|
|
|
console.log('pages',pages) |
|
|
|
|
|
|
|
// let canvas = document.createElement('canvas') |
|
|
|
// const png = canvas.toDataURL('img/png') |
|
|
|
// const imagePDF = await pdfDoc.embedPng(png) |
|
|
|
await getInitWatermark().then((res) => { |
|
|
|
this.watermarkInfo = res |
|
|
|
if (res.watermarkType === '1') { |
|
|
|
// 图片水印 |
|
|
|
let dom = document.getElementsByClassName('page') |
|
|
|
let canvas = document.createElement('canvas') |
|
|
|
let cxt = canvas.getContext('2d') |
|
|
|
let divImg = document.createElement('div') |
|
|
|
|
|
|
|
// 水印 |
|
|
|
const drawTextParams = { |
|
|
|
lineHeight: 50, |
|
|
|
font: customFont, |
|
|
|
size: 16, |
|
|
|
color: rgb(0.08, 0.08, 0.2), |
|
|
|
rotate: degrees(15), |
|
|
|
opacity: 0.8 |
|
|
|
} |
|
|
|
|
|
|
|
for (let index = 0; index < pages.length; index++) { |
|
|
|
const currentPage = pages[index] |
|
|
|
// 获取当前页宽高 |
|
|
|
const { width, height } = currentPage.getSize() |
|
|
|
// 要渲染的文字内容 |
|
|
|
for (let ix = 10; ix < width; ix += 300) { // 水印横向间隔 |
|
|
|
let lineNum = 0 |
|
|
|
for (let iy = 50; iy <= height; iy += 200) { // 水印纵向间隔 |
|
|
|
lineNum++ |
|
|
|
currentPage.drawText('徐华姣' + this.formateTime(), { |
|
|
|
x: lineNum & 1 ? ix : ix + 60, |
|
|
|
y: iy, |
|
|
|
...drawTextParams |
|
|
|
}) |
|
|
|
let imgScale = 0.1 |
|
|
|
//创建新的图片对象 |
|
|
|
let img = new Image(); |
|
|
|
//指定图片的URL |
|
|
|
img.src = this.watermarkInfo.context; |
|
|
|
let _this = this; |
|
|
|
//浏览器加载图片完毕后再绘制图片 |
|
|
|
img.onload = function() { |
|
|
|
//cxt.drawImage(img,0,0); |
|
|
|
cxt.rotate(-20 * Math.PI / 180) |
|
|
|
let whScale = img.width / img.height |
|
|
|
cxt.clearRect(0, 0, canvas.width, canvas.height); |
|
|
|
cxt.drawImage(img, //规定要使用的图像、画布或视频。 |
|
|
|
0, 0, //开始剪切的 x 坐标位置。 |
|
|
|
img.width, img.height, //被剪切图像的高度。 |
|
|
|
0, 50,//在画布上放置图像的 x 、y坐标位置。 |
|
|
|
img.width * imgScale, img.height * imgScale //要使用的图像的宽度、高度 |
|
|
|
) |
|
|
|
|
|
|
|
divImg.style.opacity = parseFloat(_this.watermarkInfo.transparency) / 100 |
|
|
|
divImg.style.background = 'url(' + canvas.toDataURL('image/png') + ') left top repeat' |
|
|
|
_this.drawImage2(divImg,dom) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (res.watermarkType === '0') { |
|
|
|
const rgbaValue = this.watermarkInfo.transparency; |
|
|
|
const startIndex = rgbaValue.indexOf('('); // 找到第一个括号的位置 |
|
|
|
const endIndex = rgbaValue.lastIndexOf(','); // 找到透明度部分的位置 |
|
|
|
|
|
|
|
const rgbPart = 'rgb' + rgbaValue.slice(startIndex, endIndex) + ')'; // 提取 RGB 部分 |
|
|
|
this.initOpacity = rgbaValue.slice(endIndex + 1, -1); // 提取透明度部分 |
|
|
|
|
|
|
|
// 图片水印 |
|
|
|
// let dom = document.getElementsByClassName('page') |
|
|
|
// let canvas = document.createElement('canvas') |
|
|
|
// let cxt = canvas.getContext('2d') |
|
|
|
// let divImg = document.createElement('div') |
|
|
|
const rgbValues = rgbPart.slice(4, -1).split(', ').map(value => { |
|
|
|
const color = Number(value) / 255; |
|
|
|
return color === 1 || color === 0 ? parseInt(color.toFixed(0)) : parseFloat(color.toFixed(2)); |
|
|
|
}); |
|
|
|
// const color = `rgb(${rgbValues.join(', ')})`; |
|
|
|
this.initColor = { |
|
|
|
red: rgbValues[0], |
|
|
|
green: rgbValues[1], |
|
|
|
blue: rgbValues[2], |
|
|
|
type: "RGB" |
|
|
|
} |
|
|
|
|
|
|
|
// let imgScale = 0.3 |
|
|
|
// //创建新的图片对象 |
|
|
|
// let img = new Image(); |
|
|
|
// //指定图片的URL |
|
|
|
// img.src = this.logo; |
|
|
|
// //浏览器加载图片完毕后再绘制图片 |
|
|
|
// img.onload = function() { |
|
|
|
// //cxt.drawImage(img,0,0); |
|
|
|
// cxt.rotate(-20 * Math.PI / 180) |
|
|
|
// let whScale = img.width / img.height |
|
|
|
// cxt.clearRect(0, 0, canvas.width, canvas.height); |
|
|
|
// cxt.drawImage(img, //规定要使用的图像、画布或视频。 |
|
|
|
// 0, 0, //开始剪切的 x 坐标位置。 |
|
|
|
// img.width, img.height, //被剪切图像的高度。 |
|
|
|
// 0, 50,//在画布上放置图像的 x 、y坐标位置。 |
|
|
|
// img.width * imgScale, img.height * imgScale //要使用的图像的宽度、高度 |
|
|
|
// ) |
|
|
|
// divImg.style.opacity = 0.3 |
|
|
|
// divImg.style.background = 'url(' + canvas.toDataURL('image/png') + ') left top repeat' |
|
|
|
// drawImage2(divImg,dom) |
|
|
|
// } |
|
|
|
const drawTextParams = { |
|
|
|
lineHeight: 50, |
|
|
|
font: customFont, |
|
|
|
size: parseInt(this.watermarkInfo.watermarkFont), |
|
|
|
color: this.initColor, |
|
|
|
rotate: degrees(15), |
|
|
|
opacity: parseFloat(this.initOpacity) |
|
|
|
} |
|
|
|
|
|
|
|
// function drawImage2 (div,dom) { |
|
|
|
// div.style.pointerEvents = 'none' |
|
|
|
// div.className = 'weterbox' |
|
|
|
// div.style.top = 0 |
|
|
|
// div.style.left = 0 |
|
|
|
// div.style.position = 'absolute' |
|
|
|
// div.style.zIndex = '100000' |
|
|
|
// div.style.width = '100%' |
|
|
|
// div.style.height = '100%' |
|
|
|
// if( dom.length > 0){ |
|
|
|
// for(let i = 0; i< dom.length;i++){ |
|
|
|
// let child = dom[i].getElementsByClassName('weterbox') |
|
|
|
// if(child.length > 0){ |
|
|
|
// dom[i].removeChild(child[0]) |
|
|
|
// } |
|
|
|
// dom[i].appendChild(div.cloneNode(true)) |
|
|
|
// } |
|
|
|
// } |
|
|
|
// } |
|
|
|
for (let index = 0; index < pages.length; index++) { |
|
|
|
const currentPage = pages[index] |
|
|
|
// 获取当前页宽高 |
|
|
|
const { width, height } = currentPage.getSize() |
|
|
|
// 要渲染的文字内容 |
|
|
|
for (let ix = 10; ix < width; ix += 300) { // 水印横向间隔 |
|
|
|
let lineNum = 0 |
|
|
|
for (let iy = 50; iy <= height; iy += 200) { // 水印纵向间隔 |
|
|
|
lineNum++ |
|
|
|
currentPage.drawText(this.watermarkInfo.context, { |
|
|
|
x: lineNum & 1 ? ix : ix + 60, |
|
|
|
y: iy, |
|
|
|
...drawTextParams |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err) |
|
|
|
}) |
|
|
|
|
|
|
|
const pdfBytes = await pdfDoc.save() |
|
|
|
this.pdfDoc = await PDFJS.getDocument(pdfBytes).promise |
|
|
|
this.pdf_pages = this.pdfDoc.numPages |
|
|
|
this.$nextTick(() => this.renderPagePdf()) |
|
|
|
}, |
|
|
|
drawImage2 (div,dom) { |
|
|
|
div.style.pointerEvents = 'none' |
|
|
|
div.className = 'weterbox' |
|
|
|
div.style.top = 0 |
|
|
|
div.style.left = 0 |
|
|
|
div.style.position = 'absolute' |
|
|
|
div.style.zIndex = '100000' |
|
|
|
div.style.width = '100%' |
|
|
|
div.style.height = '100%' |
|
|
|
if( dom.length > 0){ |
|
|
|
for(let i = 0; i< dom.length;i++){ |
|
|
|
let child = dom[i].getElementsByClassName('weterbox') |
|
|
|
if(child.length > 0){ |
|
|
|
dom[i].removeChild(child[0]) |
|
|
|
} |
|
|
|
dom[i].appendChild(div.cloneNode(true)) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
async renderPagePdf(num = 1) { |
|
|
|
this.currentPage = num |
|
|
|
const page = await this.pdfDoc.getPage(num) |
|
|
@ -228,7 +264,6 @@ export default { |
|
|
|
viewport: viewport, |
|
|
|
eventBus: eventBus |
|
|
|
}) |
|
|
|
|
|
|
|
textLayer.setTextContent(textContent) |
|
|
|
textLayer.render() |
|
|
|
}) |
|
|
@ -238,7 +273,68 @@ export default { |
|
|
|
return this.renderPagePdf(num + 1) |
|
|
|
}) |
|
|
|
} |
|
|
|
chapter(this.arr) |
|
|
|
|
|
|
|
// 归档章数据获取操作 |
|
|
|
this.getFilingsealFormat() |
|
|
|
}, |
|
|
|
getFilingsealFormat() { |
|
|
|
FetchGetFilingsealFormat().then((res) => { |
|
|
|
this.formatOptions = res |
|
|
|
if (this.selectedCategory.filingId) { |
|
|
|
res.map(item => { |
|
|
|
if (item.id === this.selectedCategory.filingId) { |
|
|
|
this.filingName = item.name |
|
|
|
this.changeFormat(this.selectedCategory.filingId) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err) |
|
|
|
}) |
|
|
|
}, |
|
|
|
changeFormat(value) { |
|
|
|
this.formatData = [] |
|
|
|
if (value) { |
|
|
|
FetchGetFilingsealFormatDtails(value).then((res) => { |
|
|
|
this.formatData = res.sort((a, b) => { |
|
|
|
if (a.row === b.row) { |
|
|
|
return a.line - b.line // 如果 row 相同,则按 line 升序排序 |
|
|
|
} else { |
|
|
|
return a.row - b.row // 否则,按 row 升序排序 |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.formatData.length; i++) { |
|
|
|
for (let j = 0; j < this.fileParentInfo.length; j++) { |
|
|
|
if (this.formatData[i].fieldName === this.fileParentInfo[j].fieldName) { |
|
|
|
this.formatData[i].context = this.fileParentInfo[j].context |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const chunkSize = 3; |
|
|
|
const chapterArray = []; |
|
|
|
|
|
|
|
for (let i = 0; i < this.formatData.length; i += chunkSize) { |
|
|
|
// const chunk = this.formatData.slice(i, i + chunkSize); |
|
|
|
// const obj = {}; |
|
|
|
// chunk.forEach(item => { |
|
|
|
// obj[item.fieldName] = item.context; |
|
|
|
// }); |
|
|
|
const obj = { |
|
|
|
zongshu: this.formatData[i].context || '', |
|
|
|
yilei: this.formatData[i + 1].context || '', |
|
|
|
erlei: this.formatData[i + 2].context || '' |
|
|
|
}; |
|
|
|
chapterArray.push(obj); |
|
|
|
} |
|
|
|
chapter(chapterArray) |
|
|
|
|
|
|
|
}).catch(err => { |
|
|
|
console.log(err) |
|
|
|
}) |
|
|
|
} |
|
|
|
}, |
|
|
|
// , |
|
|
|
// nextPage() { |
|
|
@ -275,14 +371,14 @@ export default { |
|
|
|
const { width, height } = noPage.getSize() |
|
|
|
for (let i = 0; i < 10; i++) { |
|
|
|
for (let j = 0; j < 3; j++) { |
|
|
|
noPage.drawText('张三-2023-01-01', { |
|
|
|
noPage.drawText(this.watermarkInfo.context, { |
|
|
|
x: 230 * j, |
|
|
|
y: (height / 4) * i, |
|
|
|
font: fontkitFile, |
|
|
|
size: 16, |
|
|
|
color: rgb(0.46, 0.53, 0.6), |
|
|
|
size: parseInt(this.watermarkInfo.watermarkFont), |
|
|
|
color: this.initColor, |
|
|
|
rotate: degrees(45), |
|
|
|
opacity: 0.3 |
|
|
|
opacity: parseFloat(this.initOpacity) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|