md
This commit is contained in:
parent
82763fa5f4
commit
7416f5a8af
44
src/components/Barcode/index.vue
Normal file
44
src/components/Barcode/index.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<script>
|
||||
import { defineComponent, h } from 'vue';
|
||||
import JsBarcode from 'jsbarcode'
|
||||
|
||||
export default defineComponent({
|
||||
name: "VueBarcode",
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'canvas',
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$props: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler() {
|
||||
if (this.$el) {
|
||||
this.generate();
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.generate();
|
||||
},
|
||||
methods: {
|
||||
generate() {
|
||||
JsBarcode(this.$el, String(this.value), this.options);
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return h(this.tag, this.$slots.default);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
536
src/components/PdfViewer/A4Viewer.vue
Normal file
536
src/components/PdfViewer/A4Viewer.vue
Normal file
@ -0,0 +1,536 @@
|
||||
<template>
|
||||
<!-- v-if="pdfUrl" -->
|
||||
<div class="pdf-viewer grid2" >
|
||||
<div style="position: relative;">
|
||||
<div class="pdf-bar">
|
||||
<div class="zoom-minus" @click="zoomIn">
|
||||
<i class="el-icon-minus" title="缩小"></i>
|
||||
</div>
|
||||
<div class="scale" >
|
||||
<el-input v-model.number="scale" size="mini" @keyup.enter.native="setScaleValue">
|
||||
<template slot="append">%</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="zoom-plus" @click="zoomOut">
|
||||
<i class="el-icon-plus" title="放大"></i>
|
||||
</div>
|
||||
<div class="prev" @click="prePage">
|
||||
上一页
|
||||
</div>
|
||||
<div class="page">
|
||||
<el-input-number
|
||||
v-model.number="currentPage"
|
||||
:min="0"
|
||||
:max="pageCount"
|
||||
size="mini"
|
||||
/>
|
||||
</div>
|
||||
<div class="page-count">/ {{ pageCount }}</div>
|
||||
<div class="next" @click="nextPage">
|
||||
下一页
|
||||
</div>
|
||||
<div class="tools">
|
||||
<div style="width:100%;text-align: right;">
|
||||
<!-- <el-button title="" type="primary" v-if="isA4" @click="showSinglePage(1)">切换单页</el-button> -->
|
||||
<!-- <el-button title="" type="primary" v-else @click="showA4Page(1)">切换A4</el-button> -->
|
||||
<el-button title="" type="primary" icon="el-icon-download" @click="downPDF">下载</el-button>
|
||||
<el-button title="" type="primary" icon="el-icon-printer" @click="printPDF">打印</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="min-height:1600px;margin: 0 auto;overflow: auto;">
|
||||
<!-- <el-scrollbar style="height:800px"> -->
|
||||
<!-- </el-scrollbar> -->
|
||||
<div class="pdf-wrapper">
|
||||
<pdf
|
||||
:src="currentPdfUrl"
|
||||
:page="page"
|
||||
@num-pages="thisPageCount = $event"
|
||||
@page-loaded="onPageLoaded($event)"
|
||||
ref="pdf"
|
||||
></pdf>
|
||||
<!-- v-drag -->
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <div>
|
||||
<XdPdf :pdfUrl="loadPdfUrl"></XdPdf>
|
||||
</div> -->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import printJS from 'print-js'
|
||||
// npm i pdfjs-dist@2.5.207
|
||||
// npm i vue-pdf@4.2.0
|
||||
import pdf from 'xd-vue-pdf'
|
||||
import PdfUtils from '@/utils/pdfUtils.js';
|
||||
export default {
|
||||
components: { pdf },
|
||||
props: {
|
||||
pdfList:{
|
||||
type: Array,
|
||||
},
|
||||
startPage: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
|
||||
isLoadComplete:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading:false,
|
||||
|
||||
resetCountKey:1,
|
||||
loadPdfUrl:null,
|
||||
|
||||
// 单页模式
|
||||
cacheFileList:this.pdfList,
|
||||
isA4:true,
|
||||
|
||||
page: 1,
|
||||
currentPage: 1,
|
||||
pageCount: this.pdfList.length,
|
||||
|
||||
// A4 模式
|
||||
cacheA4FileList:[],
|
||||
thisPageCount:1,
|
||||
|
||||
|
||||
scale: 20,
|
||||
preScale: 20,
|
||||
|
||||
pdfUtils:new PdfUtils(),
|
||||
|
||||
loading: false,
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentPdfUrl() {
|
||||
if (!this.loadPdfUrl) return ''
|
||||
const publicPath ='/static/'
|
||||
return pdf.createLoadingTask({
|
||||
url: this.loadPdfUrl,
|
||||
cMapUrl: `${publicPath}cmaps/`,
|
||||
cMapPacked: true
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pdfList(){
|
||||
this.cacheFileList=this.pdfList;
|
||||
this.initA4List();
|
||||
this.showFirstFile();
|
||||
},
|
||||
thisPageCount(value) {
|
||||
if(this.isA4){
|
||||
this.doScale(75);
|
||||
}else{
|
||||
this.doScale(20);
|
||||
}
|
||||
},
|
||||
|
||||
isLoadComplete(newVal,oldVal){
|
||||
this.showA4Page(1);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initA4List();
|
||||
this.showFirstFile();
|
||||
window.addEventListener('mousewheel', this.handleScroll, { passive: false })
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
initA4List(){
|
||||
this.cacheA4FileList=[];
|
||||
const newList = Object.assign([], this.pdfList);
|
||||
if(newList&&newList.length>4){
|
||||
let spliteArr = (array = [], subGroupLength = 0) => {
|
||||
let index = 0;
|
||||
const newArray = [];
|
||||
while (index < array.length) {
|
||||
newArray.push(array.slice(index, index += subGroupLength));
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
const subPdfList=spliteArr(newList, 4);
|
||||
for (let i=0; i < subPdfList.length;i++){
|
||||
let fileItem={
|
||||
"billCode":"page-"+(i+1),
|
||||
"pdfUrl":null,
|
||||
"childreen":subPdfList[i]
|
||||
}
|
||||
this.cacheA4FileList.push(fileItem);
|
||||
}
|
||||
}else{
|
||||
let fileItem={
|
||||
"billCode":"page-"+1,
|
||||
"pdfUrl":null,
|
||||
"childreen":newList
|
||||
}
|
||||
this.cacheA4FileList.push(fileItem);
|
||||
}
|
||||
},
|
||||
showFirstFile(){
|
||||
if(this.isA4){
|
||||
this.scale=75;
|
||||
this.preScale=75;
|
||||
this.pageCount=this.cacheA4FileList.length;
|
||||
setTimeout( this.showA4Page(this.cacheA4FileList.length),3000);
|
||||
}else{
|
||||
this.scale=20;
|
||||
this.preScale=20;
|
||||
this.pageCount=this.cacheFileList.length;
|
||||
setTimeout( this.showSinglePage(1),2000);
|
||||
}
|
||||
|
||||
this.resetCountKey++;
|
||||
},
|
||||
addPdfUrl(billCode,pdfUrl){
|
||||
let item={
|
||||
"billCode":billCode,
|
||||
"pdfUrl":pdfUrl
|
||||
}
|
||||
this.pdfList.push(item);
|
||||
},
|
||||
handleScroll(e){
|
||||
// 判断是不是按下ctrl键
|
||||
if(e.ctrlKey) {
|
||||
// 取消浏览器默认的放大缩小网页行为
|
||||
e.preventDefault()
|
||||
// 判断是向上滚动还是向下滚动
|
||||
if (e.deltaY > 0) {
|
||||
// 放大重写,业务代码
|
||||
this.zoomOut()
|
||||
} else {
|
||||
// 缩小重写,业务代码
|
||||
this.zoomIn()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onPageLoaded(currentPage){
|
||||
|
||||
|
||||
if(this.isA4){
|
||||
// this.page = 1;
|
||||
// this.doScale(75);
|
||||
}else{
|
||||
// this.currentPage=1;
|
||||
// this.page = 1;
|
||||
// this.doScale(20);
|
||||
}
|
||||
},
|
||||
|
||||
doScale(val){
|
||||
if (isNaN(val)) {
|
||||
this.scale = this.preScale
|
||||
return
|
||||
}
|
||||
if (val< 10) {
|
||||
this.scale = 10
|
||||
}
|
||||
if (val > 200) {
|
||||
this.scale = 200
|
||||
}
|
||||
this.preScale = this.scale
|
||||
this.$refs.pdf.$el.style.width = parseInt(this.scale) + '%';
|
||||
this.$refs.pdf.$el.style.margin = "0 auto";
|
||||
},
|
||||
setScaleValue(e) {
|
||||
this.doScale(e.target.value)
|
||||
},
|
||||
zoomIn() {
|
||||
if (this.scale > 20) {
|
||||
this.scale += -5
|
||||
this.doScale(this.scale );
|
||||
}
|
||||
},
|
||||
zoomOut() {
|
||||
if (this.scale < 200) {
|
||||
this.scale += 5
|
||||
this.doScale(this.scale );
|
||||
}
|
||||
},
|
||||
prePage() {
|
||||
if(!this.isA4){
|
||||
let fileNo = this.currentPage - 1
|
||||
if (fileNo < 1) return
|
||||
this.currentPage = fileNo
|
||||
this.showSinglePage(this.currentPage)
|
||||
}
|
||||
else{
|
||||
let fileNo = this.currentPage - 1
|
||||
if (fileNo < 1) return
|
||||
this.currentPage = fileNo
|
||||
this.showA4Page(this.currentPage)
|
||||
}
|
||||
},
|
||||
nextPage() {
|
||||
if(!this.isA4){
|
||||
let fileNo = this.currentPage + 1
|
||||
if (fileNo > this.pageCount) return
|
||||
this.currentPage = fileNo
|
||||
this.showSinglePage(this.currentPage)
|
||||
}
|
||||
else{
|
||||
let fileNo = this.currentPage + 1
|
||||
if (fileNo > this.pageCount) return
|
||||
this.currentPage = fileNo
|
||||
this.showA4Page(this.currentPage)
|
||||
}
|
||||
},
|
||||
// 下载
|
||||
downPDF() {
|
||||
// 下载所有预览的PDF文件
|
||||
if(this.isA4){
|
||||
if(this.cacheA4FileList&&this.cacheA4FileList.length>0){
|
||||
this.cacheA4FileList.forEach(async item=>{
|
||||
if(!item.pdfUrl){
|
||||
let thisSubList=item.childreen;
|
||||
let needGenList=[];
|
||||
for(let j=0;j<thisSubList.length;j++){
|
||||
needGenList.push(thisSubList[j].pdfBase64)
|
||||
}
|
||||
item.pdfUrl=await this.pdfUtils.mergePdfToA4(needGenList);
|
||||
this.downPdfFile(item.billCode,item.pdfUrl);
|
||||
}else{
|
||||
this.downPdfFile(item.billCode,item.pdfUrl);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if(this.cacheFileList&&this.cacheFileList.length>0){
|
||||
this.cacheFileList.forEach( item=>{
|
||||
if(!item.pdfUrl){
|
||||
item.pdfUrl = this.pdfUtils.getBlobUrl(item.pdfBase64);
|
||||
}
|
||||
this.downPdfFile(item.billCode,item.pdfUrl);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
downPdfFile(fileName,pdfUrl){
|
||||
var tempLink = document.createElement('a')
|
||||
tempLink.style.display = 'none'
|
||||
tempLink.href = pdfUrl
|
||||
tempLink.setAttribute('download', fileName+'.pdf')
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.setAttribute('target', '_blank')
|
||||
}
|
||||
document.body.appendChild(tempLink)
|
||||
tempLink.click()
|
||||
document.body.removeChild(tempLink)
|
||||
},
|
||||
// 打印
|
||||
printPDF() {
|
||||
if(this.isA4){
|
||||
printJS(this.loadPdfUrl);
|
||||
}else{
|
||||
this.$emit("onPrint");
|
||||
}
|
||||
},
|
||||
showSinglePage(page){
|
||||
this.isA4 = false;
|
||||
if(!page || Object.is(page, NaN)){
|
||||
page=1;
|
||||
}
|
||||
|
||||
this.pageCount=this.cacheFileList.length;
|
||||
const thisPage=this.cacheFileList[page-1];
|
||||
|
||||
const pdfBase64 = thisPage.pdfBase64;
|
||||
|
||||
this.loadPdfUrl = this.pdfUtils.getBlobUrl(pdfBase64);
|
||||
|
||||
this.doScale(20);
|
||||
this.resetCountKey++;
|
||||
},
|
||||
async showA4Page(page){
|
||||
this.isA4 = true
|
||||
if(!page || Object.is(page, NaN)){
|
||||
page=1;
|
||||
}
|
||||
|
||||
if(!this.cacheA4FileList || this.cacheA4FileList.length==0){
|
||||
return;
|
||||
}
|
||||
|
||||
const loadingInstance = this.$loading({
|
||||
text: '正在生成A4预览...'
|
||||
})
|
||||
|
||||
this.pageCount=this.cacheA4FileList.length;
|
||||
|
||||
// 分页生成文件,只渲染第一页
|
||||
let thisSubList=this.cacheA4FileList[page-1].childreen;
|
||||
let needGenList=[];
|
||||
for(let j=0;j<thisSubList.length;j++){
|
||||
needGenList.push(thisSubList[j].pdfBase64)
|
||||
}
|
||||
|
||||
let pdfUrl=await this.pdfUtils.mergePdfToA4(needGenList);
|
||||
if(pdfUrl){
|
||||
loadingInstance.close();
|
||||
this.cacheA4FileList[page-1].pdfUrl=pdfUrl;
|
||||
this.loadPdfUrl=this.cacheA4FileList[page-1].pdfUrl;
|
||||
}
|
||||
|
||||
this.resetCountKey++;
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.grid1 {
|
||||
height: 200px;
|
||||
background-image:
|
||||
linear-gradient(45deg, #8d8b8b 25%, transparent 0),
|
||||
linear-gradient(-45deg, #8d8b8b 25%, transparent 0),
|
||||
linear-gradient(45deg, transparent 75%, #8d8b8b 0),
|
||||
linear-gradient(-45deg, transparent 75%, #8d8b8b 0);
|
||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0;
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
.grid2 {
|
||||
height: 200px;
|
||||
background-image: radial-gradient(circle, rgb(165, 165, 165) 1px, #fff 1px);
|
||||
background-size: 20px 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
|
||||
.grid3 {
|
||||
height: 200px;
|
||||
background-image:
|
||||
linear-gradient(to right, rgb(203 213 225) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgb(203 213 225) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.grid4 {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Crect width='40' height='40' fill='%23fff' /%3E%3Crect x='50%' width='1' height='100%' fill='rgb(203 213 225)' /%3E%3Crect y='50%' width='100%' height='1' fill='rgb(203 213 225)' /%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.showA4 {
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
width: 1920px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.pdf-viewer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// overflow: hidden;
|
||||
overflow: auto;
|
||||
// height: 100%;
|
||||
font-family: PingFang SC;
|
||||
// width: 100%;
|
||||
// position: relative;
|
||||
// background: #eeeeee;
|
||||
// background: #dcdcdc;
|
||||
|
||||
.tools {
|
||||
display: flex;
|
||||
z-index: 9999;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 30px;
|
||||
}
|
||||
.pdf-bar {
|
||||
position: absolute;
|
||||
// position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 1;
|
||||
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
border: 1px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
background: #f8f8f8;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
& > div {
|
||||
min-width: 36px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
i {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
}
|
||||
::v-deep .el-input--mini {
|
||||
input {
|
||||
padding: 0 8px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
.el-input-group__append {
|
||||
padding: 0 6px;
|
||||
color: #666;
|
||||
cursor: auto;
|
||||
}
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
margin-left: 10px;
|
||||
width: 40px;
|
||||
.el-input-number__decrease {
|
||||
display: none;
|
||||
}
|
||||
.el-input-number__increase {
|
||||
display: none;
|
||||
}
|
||||
.el-input--mini {
|
||||
input {
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.prev {
|
||||
margin-left: 16px;
|
||||
}
|
||||
.scale,
|
||||
.page {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.page-count {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.pdf-wrapper {
|
||||
position: absolute;
|
||||
margin-top: 70px;
|
||||
width: 100%;
|
||||
height: calc(100% - 70px);
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user