【新增】标签目录和打印组件

This commit is contained in:
yanran200830
2024-10-16 18:15:19 +08:00
parent 4a90536696
commit 4d8b597abf
19 changed files with 5905 additions and 2624 deletions

View File

@@ -0,0 +1,498 @@
<template>
<div class="print">
<div class="print-wrapper">
<div class="left">
<div class="left-wrapper">
<div class="title">基础元素</div>
<div class="left-item__wrapper">
<div class="ep-draggable-item item" tid="defaultModule.text">
<i class="iconfont">&#xe649;</i>
<span>文本</span>
</div>
<div v-if="false" class="ep-draggable-item item" tid="defaultModule.image">
<i class="iconfont">&#xe61e;</i>
<span>图片</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.longText">
<i class="iconfont">&#xe7dc;</i>
<span>长文</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.table">
<i class="iconfont">&#xea3f;</i>
<span>表格</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.html">
<i class="iconfont">&#xe633;</i>
<span>html</span>
</div>
</div>
<div class="title">辅助元素</div>
<div class="left-item__wrapper">
<div class="ep-draggable-item item" tid="defaultModule.hline">
<i class="iconfont">&#xe7dd;</i>
<span>横线</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.vline">
<i class="iconfont">&#xe70f;</i>
<span>竖线</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.rect">
<i class="iconfont">&#xe620;</i>
<span>矩形</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.oval">
<i class="iconfont">&#xe76a;</i>
<span>圆形</span>
</div>
</div>
<div class="title">常用元素</div>
<div class="left-item__wrapper" id="custom-provider">
<div class="ep-draggable-item item" tid="defaultModule.hline">
<i class="iconfont">&#xe7dd;</i>
<span>横线</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.vline">
<i class="iconfont">&#xe70f;</i>
<span>竖线</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.rect">
<i class="iconfont">&#xe620;</i>
<span>矩形</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.oval">
<i class="iconfont">&#xe76a;</i>
<span>圆形</span>
</div>
</div>
</div>
</div>
<div class="center">
<div class="center-header">
<div class="paper">
<el-button-group size="small">
<template v-for="(value, type) in paperTypes">
<el-button size="small" :type="curPaperType === type ? 'primary' : ''" @click="setPaper(type,value)" :key="type">
{{ type }}
</el-button>
</template>
<el-popover v-model="paperPopVisible" placement="top" :width="260" trigger="click">
<div>
<div style="font-size: 16px; font-weight: bold">设置纸张宽高(mm)</div>
<div style="margin-top: 10px">
<el-input size="small" style="margin-bottom: 10px" v-model="paperWidth" type="number" placeholder="宽(mm)" />
<el-input size="small" v-model="paperHeight" type="number" placeholder="高(mm)" />
</div>
<el-button style="margin-top: 12px" size="small" @click.stop="setPaperOther">确定</el-button>
</div>
<el-button slot="reference" size="small" :type="'other' == curPaperType ? 'primary' : ''">自定义纸张</el-button>
</el-popover>
</el-button-group>
<!-- <div class="scale">
<el-button @click="changeScale(false)" size="small">
<el-icon size="18"><ZoomOut /></el-icon>
</el-button>
<div style="margin: 0 4px; width: 40px">{{ (scaleValue * 100).toFixed(0) }}%</div>
<el-button @click="changeScale(true)" size="small">
<el-icon size="18"><ZoomIn /></el-icon>
</el-button>
</div> -->
</div>
</div>
<div class="center-wrapper">
<div id="hiprint-printTemplate"></div>
</div>
</div>
<div class="right">
<div id="PrintElementOptionSetting"></div>
</div>
</div>
<ai-dialog :visible.sync="isShowPreview" title="预览" width="1200" customFooter>
<div class="print-viewer" v-html="html"></div>
<div class="dialog-footer" slot="footer">
<el-button @click="isShowPreview = false">取消</el-button>
</div>
</ai-dialog>
</div>
</template>
<script>
import { hiprint, defaultElementTypeProvider, disAutoConnect } from 'vue-plugin-hiprint'
import { newHiprintPrintTemplate } from '@/utils/template-helper'
import template from './template'
import printData from './printData'
import { customProvider } from './customProvider'
disAutoConnect()
export default {
props: {
list: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
html: '',
isShowPreview: false,
hiprintTemplate: null,
curPaper: {
type: 'other',
width: 200,
height: 200
},
paperTypes: {
'A3': {
width: 420,
height: 296.6
},
'A4': {
width: 210,
height: 296.6
},
'A5': {
width: 210,
height: 147.6
},
'B3': {
width: 500,
height: 352.6
},
'B4': {
width: 250,
height: 352.6
},
'B5': {
width: 250,
height: 175.6
}
},
paperPopVisible: false,
paperWidth: '80',
paperHeight: '60'
}
},
computed: {
curPaperType() {
let type = 'other'
let types = this.paperTypes
for (const key in types) {
let item = types[key]
let {width, height} = this.curPaper
if (item.width === width && item.height === height) {
type = key
}
}
return type
}
},
mounted() {
hiprint.init({
providers: [defaultElementTypeProvider(), customProvider({})]
})
this.buildLeftElement()
this.buildDesigner()
},
methods: {
buildLeftElement() {
hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
$('#custom-provider').empty()
hiprint.PrintElementTypeManager.build($('#custom-provider'), 'customProvider')
},
buildDesigner() {
$('#hiprint-printTemplate').empty()
console.log(template)
this.hiprintTemplate = newHiprintPrintTemplate('temulables', {
template: template,
settingContainer: '#PrintElementOptionSetting',
onImageChooseClick: (target) => {
let input = document.createElement('input')
input.setAttribute('type', 'file')
input.click()
input.onchange = function () {
var file = this.files[0]
var reader = new FileReader()
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file)
reader.onloadend = function () {
target.refresh(reader.result)
}
}
}
input.remove()
}
})
this.$nextTick(() => {
this.hiprintTemplate.design('#hiprint-printTemplate', {
grid: true
})
})
},
setPaperOther () {
let value = {}
value.width = this.paperWidth
value.height = this.paperHeight
this.setPaper('other', value)
this.paperPopVisible = false
},
setPaper(type, value) {
try {
if (Object.keys(this.paperTypes).includes(type)) {
this.curPaper = {type: type, width: value.width, height: value.height}
this.hiprintTemplate.setPaper(value.width, value.height)
} else {
this.curPaper = {type: 'other', width: value.width, height: value.height}
this.hiprintTemplate.setPaper(value.width, value.height)
}
} catch (error) {
this.$message.error(`操作失败: ${error}`)
}
},
print() {
let options = { leftOffset: 0, topOffset: 0 }
let ext = {
callback: () => {
console.log('浏览器打印窗口已打开')
},
styleHandler: () => {
return '<style></style>'
}
}
const list = this.labels
this.hiprintTemplate.print(list)
},
elementToString(el) {
const node = document.createElement('div')
node.appendChild(el)
return node.innerHTML
},
savePdf() {
const list = this.labels
this.hiprintTemplate.toPdf(printData, '测试导出pdf')
},
getHtml() {
const list = this.labels
this.html = this.elementToString(this.hiprintTemplate.getHtml(list)[0])
console.log(this.html)
this.isShowPreview = true
},
clearPaper() {
this.hiprintTemplate.clear()
},
exportJson() {
return this.hiprintTemplate.getJson()
}
}
}
</script>
<style lang="scss" scoped>
.print {
height: 100%;
.print-wrapper {
display: flex;
height: calc(100vh - 180px);
::v-deep(.prop-tab-items) {
background-color: transparent !important;
.prop-tab-item {
background-color: transparent !important;
.tab-title {
font-size: 14px;
}
}
}
::v-deep(.hiprint-option-items .hiprint-option-item-label) {
width: 100%;
margin-bottom: 14px;
text-align: left;
font-size: 14px;
}
::v-deep(.hiprint-printPanel) {
display: block;
& > div {
// margin: 0 auto !important;
}
}
::v-deep(.minicolors) {
flex: 1;
width: inherit;
input {
width: 100% !important;
}
}
::v-deep(.hiprint-option-item-field) {
width: 100%;
font-size: 14px;
input {
height: 24px;
}
}
::v-deep(.hiprint-option-item-row) {
display: block;
}
::v-deep(.prop-tab-items) {
margin-bottom: 10px;
}
::v-deep(.hiprint-option-items),
::v-deep(.prop-tabs) {
background-color: transparent !important;
}
.left {
width: 350px;
height: 100%;
overflow-y: auto;
.title {
margin: 14px 0;
}
.left-item__wrapper {
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
.item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100px;
margin-bottom: 10px;
margin-right: 10px;
padding: 10px 0;
background-color: #eee;
border-radius: 4px;
&:nth-of-type(3n) {
margin-right: 0;
}
span {
margin-top: 10px;
}
}
::v-deep(ul) {
margin: 0;
padding: 0;
list-style: none;
.title {
display: none;
}
ul {
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
li {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100px;
margin-bottom: 10px;
margin-right: 10px;
background-color: #eee;
border-radius: 4px;
&:nth-of-type(3n) {
margin-right: 0;
}
a {
margin-top: 10px;
padding: 10px 0;
}
}
}
}
}
}
.center {
display: flex;
position: relative;
flex-direction: column;
flex: 1;
overflow: hidden;
padding: 0 10px;
color: #000;
.center-wrapper {
flex: 1;
overflow-x: auto;
overflow-y: auto;
width: 100%;
padding: 20px 20px 10px;
}
.center-header {
width: 100%;
padding-bottom: 10px;
.paper {
display: flex;
position: relative;
align-items: center;
justify-content: center;
}
.scale {
display: flex;
align-items: center;
margin: 0 10px;
}
}
}
.right {
width: 300px;
overflow-y: auto;
overflow-x: hidden;
}
}
.print-viewer {
color: #000;
}
}
</style>

View File

@@ -0,0 +1,66 @@
import { hiprint } from 'vue-plugin-hiprint'
export const customProvider = function (options) {
var addElementTypes = function (context) {
context.removePrintElementTypes('customProvider')
context.addPrintElementTypes('customProvider', [
new hiprint.PrintElementTypeGroup('', [
{
tid: 'providerModule1.date',
title: '业务日期',
data: '2020-01-01',
type: 'text',
options: {
field: 'date',
testData: '2020-01-01',
height: 16,
fontSize: 6.75,
fontWeight: '700',
textAlign: 'left',
textContentVerticalAlign: 'middle',
hideTitle: true
}
},
{
tid: 'providerModule1.barcode',
title: '条形码',
data: 'XS888888888',
type: 'text',
options: {
field: 'barcode',
testData: 'XS888888888',
height: 32,
fontSize: 12,
lineHeight: 18,
textAlign: 'left',
textType: 'barcode',
hideTitle: false
}
},
{
tid: 'providerModule1.qrcode',
title: '二维码',
data: 'XS888888888',
type: 'text',
options: {
field: '',
testData: '',
height: 32,
fontSize: 12,
lineHeight: 18,
textType: 'qrcode',
hideTitle: false
}
},
{
tid: 'providerModule1.image',
title: 'Logo',
data: 'https://foruda.gitee.com/avatar/1677050350324030848/5400665_ccsimple_1591166830.png!avatar200',
type: 'image'
}
])
])
}
return {
addElementTypes: addElementTypes
}
}

View File

@@ -0,0 +1,10 @@
export default {
name: '黄磊',
password: '12346',
barcode: 'XS888888888',
table: [
{ id: '1', name: '王小可', gender: '男', count: '120', amount: '9089元' },
{ id: '2', name: '梦之遥', gender: '女', count: '20', amount: '89元' },
{ id: '3', name: '梦之遥', gender: '女', count: '720', amount: '29089元' }
]
}

File diff suppressed because one or more lines are too long