【新增】标签目录和打印组件
This commit is contained in:
		
							
								
								
									
										498
									
								
								src/components/print/Print.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								src/components/print/Print.vue
									
									
									
									
									
										Normal 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"></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 class="ep-draggable-item item" tid="defaultModule.html"> | ||||
|               <i class="iconfont"></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"></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: '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> | ||||
		Reference in New Issue
	
	Block a user