【新增】标签目录和打印组件
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> | ||||
							
								
								
									
										66
									
								
								src/components/print/customProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/components/print/customProvider.js
									
									
									
									
									
										Normal 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 | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/components/print/printData.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/components/print/printData.js
									
									
									
									
									
										Normal 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元' } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										1200
									
								
								src/components/print/template.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1200
									
								
								src/components/print/template.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user