511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <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"></i>
 | |
|               <span>文本</span>
 | |
|             </div>
 | |
|             <div v-if="false" class="ep-draggable-item item" tid="defaultModule.image">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>图片</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.longText">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>长文</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.table">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>表格</span>
 | |
|             </div>
 | |
|           </div>
 | |
|           <div class="title">辅助元素</div>
 | |
|           <div class="left-item__wrapper">
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.hline">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>横线</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.vline">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>竖线</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.rect">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>矩形</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.oval">
 | |
|               <i class="iconfont"></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"></i>
 | |
|               <span>横线</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.vline">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>竖线</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.rect">
 | |
|               <i class="iconfont"></i>
 | |
|               <span>矩形</span>
 | |
|             </div>
 | |
|             <div class="ep-draggable-item item" tid="defaultModule.oval">
 | |
|               <i class="iconfont"></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: 200,
 | |
|         paperHeight: 200
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     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() {
 | |
|         // eslint-disable-next-line no-undef
 | |
|         hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
 | |
|         // eslint-disable-next-line no-undef
 | |
|         $('#custom-provider').empty()
 | |
|         // eslint-disable-next-line no-undef
 | |
|         hiprint.PrintElementTypeManager.build($('#custom-provider'), 'customProvider')
 | |
|       },
 | |
| 
 | |
|       buildDesigner() {
 | |
|         // eslint-disable-next-line no-undef
 | |
|         $('#hiprint-printTemplate').empty()
 | |
|         this.hiprintTemplate = newHiprintPrintTemplate('temulables', {
 | |
|           template: {},
 | |
|           settingContainer: '#PrintElementOptionSetting',
 | |
|           fields: [{
 | |
|             field: 'html',
 | |
| 
 | |
|           }],
 | |
|           onImageChooseClick: (target) => {
 | |
|             let input = document.createElement('input')
 | |
|             input.setAttribute('type', 'file')
 | |
|             input.click()
 | |
|             input.onchange = function () {
 | |
|               var file = this.files[0]
 | |
|               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(printData)
 | |
|       },
 | |
| 
 | |
|       elementToString(el) {
 | |
|         const node = document.createElement('div')
 | |
|         node.innerHTML = el.html()
 | |
| 
 | |
|         document.querySelector('body').appendChild(node)
 | |
|         return node.innerHTML
 | |
|       },
 | |
| 
 | |
|       savePdf() {
 | |
|         const list = this.labels
 | |
|         this.hiprintTemplate.toPdf(printData, '测试导出pdf').then(v => {
 | |
|           console.log(v)
 | |
|         })
 | |
|       },
 | |
| 
 | |
|       getHtml() {
 | |
|         const list = this.labels
 | |
|         console.log(printData)
 | |
|         this.html = this.elementToString(this.hiprintTemplate.getHtml(printData))
 | |
| 
 | |
|         console.log(this.html)
 | |
| 
 | |
|         this.isShowPreview = true
 | |
|       },
 | |
| 
 | |
|       clearPaper() {
 | |
|         this.hiprintTemplate.clear()
 | |
|       },
 | |
| 
 | |
|       exportJson() {
 | |
|         return this.hiprintTemplate.getJson()
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script>
 | |
| <style lang="scss" scoped>
 | |
|   .print {
 | |
|     height: 100%;
 | |
| 
 | |
|     .temuBarCode {
 | |
|       display: flex;
 | |
|       flex-direction: column;
 | |
|       padding: 1pt 3pt;
 | |
|     }
 | |
| 
 | |
|     .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>
 |