index.vue 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. <template>
  2. <a-card>
  3. <div style="display: flex;flex-direction: column">
  4. <div class="pagetop" v-if="templateName">
  5. <div class="templateName">{{ templateName }}</div>
  6. <div class="tip">注意相同模板名称保存时将会覆盖更新</div>
  7. </div>
  8. <a-space style="margin-bottom: 10px">
  9. <a-button-group>
  10. <template v-for="(value,type) in paperTypes">
  11. <a-button :type="curPaperType === type ? 'primary' : 'info'" @click="setPaper(type,value)" :key="type">
  12. {{ type }}
  13. </a-button>
  14. </template>
  15. <a-popover v-model="paperPopVisible" title="设置纸张宽高(mm)" trigger="click">
  16. <div slot="content">
  17. <a-input-group compact style="margin: 10px 10px">
  18. <a-input type="number" v-model="paperWidth" style=" width: 100px; text-align: center"
  19. placeholder="宽(mm)"/>
  20. <a-input style=" width: 30px; border-left: 0; pointer-events: none; backgroundColor: #fff"
  21. placeholder="~" disabled
  22. />
  23. <a-input type="number" v-model="paperHeight" style="width: 100px; text-align: center; border-left: 0"
  24. placeholder="高(mm)"/>
  25. </a-input-group>
  26. <a-button type="primary" style="width: 100%" @click="otherPaper">确定</a-button>
  27. </div>
  28. <a-button :type="'other'==curPaperType?'primary':''">自定义纸张</a-button>
  29. </a-popover>
  30. </a-button-group>
  31. <a-button type="text" icon="zoom-out" @click="changeScale(false)"></a-button>
  32. <a-input-number
  33. :value="scaleValue"
  34. :min="scaleMin"
  35. :max="scaleMax"
  36. :step="0.1"
  37. disabled
  38. style="width: 70px;"
  39. :formatter="value => `${(value * 100).toFixed(0)}%`"
  40. :parser="value => value.replace('%', '')"
  41. />
  42. <a-button type="text" icon="zoom-in" @click="changeScale(true)"></a-button>
  43. <a-button type="primary" icon="redo" @click="rotatePaper()">旋转</a-button>
  44. <a-button type="primary" icon="eye" @click="preView">
  45. 预览
  46. </a-button>
  47. <a-button type="primary" icon="printer" @click="print">
  48. 直接打印
  49. </a-button>
  50. <a-button type="primary" @click="onlyPrint">
  51. Api单独打印
  52. </a-button>
  53. <a-button type="primary" @click="onlyPrint2">
  54. Api单独直接打印
  55. </a-button>
  56. <a-button type="primary" @click="showName=true">
  57. 保存模版
  58. </a-button>
  59. <a-popconfirm
  60. title="是否确认清空?"
  61. okType="danger"
  62. okText="确定清空"
  63. @confirm="clearPaper"
  64. >
  65. <a-icon slot="icon" type="question-circle-o" style="color: red"/>
  66. <a-button type="danger">
  67. 清空
  68. <a-icon type="close"/>
  69. </a-button>
  70. </a-popconfirm>
  71. <json-view :template="template"/>
  72. </a-space>
  73. <!-- <a-space style="margin-bottom: 10px">
  74. <a-button type="primary" @click="exportPdf('')">
  75. 导出获取pdf(Blob)
  76. </a-button>
  77. <a-button type="primary" @click="exportPdf('arraybuffer')">
  78. 导出获取pdf(ArrayBuffer)
  79. </a-button>
  80. <a-button type="primary" @click="exportPdf('dataurl')">
  81. 导出获取pdf(DataUrl)
  82. </a-button>
  83. <a-button type="primary" @click="exportPdf('bloburl')">
  84. 导出获取pdf(BlobUrl)
  85. </a-button>
  86. <a-button type="primary" @click="exportPdf('dataurlstring')">
  87. 导出获取pdf(DataUrlString)
  88. </a-button>
  89. <a-button type="primary" @click="exportPdf('pdfobjectnewwindow')">
  90. 导出查看pdf(PdfObjectNewWindow)
  91. </a-button>
  92. </a-space> -->
  93. <!-- <a-space style="margin-bottom: 10px">
  94. <a-button type="primary" @click="ippPrintAttr">
  95. ipp获取 打印机 参数情况
  96. </a-button>
  97. <a-button type="primary" @click="ippPrintTest">
  98. ipp打印测试
  99. </a-button>
  100. <a-button type="primary" @click="ippRequestTest">
  101. ipp请求 获取 打印机 参数情况
  102. </a-button>
  103. <a-button type="primary" @click="ippRequestPrint">
  104. ipp请求 打印测试
  105. </a-button>
  106. </a-space> -->
  107. <a-space style="margin-bottom: 10px">
  108. <a-textarea style="width:30vw" v-model="jsonIn" @pressEnter="updateJson"
  109. placeholder="复制json模板到此后 点击右侧更新"
  110. allow-clear/>
  111. <a-button type="primary" @click="updateJson">
  112. 更新json模板
  113. </a-button>
  114. <a-button type="primary" @click="exportJson">
  115. 导出json模板到 textArea
  116. </a-button>
  117. <a-textarea style="width:30vw" v-model="jsonOut" placeholder="点击左侧导出json" allow-clear/>
  118. </a-space>
  119. <a-space style="margin-bottom: 10px">
  120. <a-button type="primary" @click="getSelectEls">
  121. 获取选中元素
  122. </a-button>
  123. <a-button type="primary" @click="updateFontSize">
  124. 选中元素字体12pt
  125. </a-button>
  126. <a-button type="primary" @click="updateFontWeight">
  127. 选中元素字体Bolder
  128. </a-button>
  129. <a-button type="primary" @click="setElsSpace(true)"> 水平间距10
  130. </a-button>
  131. <a-button type="primary" @click="setElsSpace(false)"> 垂直间距10
  132. </a-button>
  133. <a-radio-group>
  134. <a-radio-button @click="setElsAlign('left')" title="左对齐">
  135. <span class="glyphicon glyphicon-object-align-left"></span>
  136. </a-radio-button>
  137. <a-radio-button @click="setElsAlign('vertical')" title="居中">
  138. <span class="glyphicon glyphicon-object-align-vertical"></span>
  139. </a-radio-button>
  140. <a-radio-button @click="setElsAlign('right')" title="右对齐">
  141. <span class="glyphicon glyphicon-object-align-right"></span>
  142. </a-radio-button>
  143. <a-radio-button @click="setElsAlign('top')" title="顶部对齐">
  144. <span class="glyphicon glyphicon-object-align-top"></span>
  145. </a-radio-button>
  146. <a-radio-button @click="setElsAlign('horizontal')" title="垂直居中">
  147. <span class="glyphicon glyphicon-object-align-horizontal"></span>
  148. </a-radio-button>
  149. <a-radio-button @click="setElsAlign('bottom')" title="底部对齐">
  150. <span class="glyphicon glyphicon-object-align-bottom"></span>
  151. </a-radio-button>
  152. <a-radio-button @click="setElsAlign('distributeHor')" title="横向分散">
  153. <span class="glyphicon glyphicon-resize-horizontal"></span>
  154. </a-radio-button>
  155. <a-radio-button @click="setElsAlign('distributeVer')" title="纵向分散">
  156. <span class="glyphicon glyphicon-resize-vertical"></span>
  157. </a-radio-button>
  158. </a-radio-group>
  159. </a-space>
  160. </div>
  161. <a-row :gutter="[8,0]">
  162. <a-col :span="4">
  163. <a-card style="height: 100vh">
  164. <a-row>
  165. <a-col :span="24" class="rect-printElement-types hiprintEpContainer">
  166. <a-row class="drag_item_title">拖拽组件列表</a-row>
  167. <a-row style="height: 100px;">
  168. <a-col :span="12" class="drag_item_box">
  169. <div>
  170. <a class="ep-draggable-item" tid="defaultModule.text" style>
  171. <span class="glyphicon glyphicon-text-width" aria-hidden="true"></span>
  172. <p class="glyphicon-class">文本</p>
  173. </a>
  174. </div>
  175. </a-col>
  176. <a-col :span="12" class="drag_item_box">
  177. <div>
  178. <a class="ep-draggable-item" tid="defaultModule.image" style>
  179. <span class="glyphicon glyphicon-picture" aria-hidden="true"></span>
  180. <p class="glyphicon-class">图片</p>
  181. </a>
  182. </div>
  183. </a-col>
  184. </a-row>
  185. <a-row style="height: 100px;">
  186. <a-col :span="12" class="drag_item_box">
  187. <div>
  188. <a class="ep-draggable-item" tid="defaultModule.longText">
  189. <span class="glyphicon glyphicon-subscript" aria-hidden="true"></span>
  190. <p class="glyphicon-class">长文</p>
  191. </a>
  192. </div>
  193. </a-col>
  194. <a-col :span="12" class="drag_item_box">
  195. <div>
  196. <a class="ep-draggable-item" tid="defaultModule.table" style>
  197. <span class="glyphicon glyphicon-th" aria-hidden="true"></span>
  198. <p class="glyphicon-class">表格</p>
  199. </a>
  200. </div>
  201. </a-col>
  202. </a-row>
  203. <a-row style="height: 100px;">
  204. <a-col :span="12" class="drag_item_box">
  205. <div>
  206. <a class="ep-draggable-item" tid="defaultModule.emptyTable" style>
  207. <span class="glyphicon glyphicon-th" aria-hidden="true"></span>
  208. <p class="glyphicon-class">空白表格</p>
  209. </a>
  210. </div>
  211. </a-col>
  212. </a-row>
  213. <a-row style="height: 100px;">
  214. <a-col :span="12" class="drag_item_box">
  215. <div>
  216. <a class="ep-draggable-item" tid="defaultModule.html" style="">
  217. <span class="glyphicon glyphicon-header" aria-hidden="true"></span>
  218. <p class="glyphicon-class">html</p>
  219. </a>
  220. </div>
  221. </a-col>
  222. <a-col :span="12" class="drag_item_box">
  223. <div>
  224. <a class="ep-draggable-item" tid="defaultModule.customText" style>
  225. <span class="glyphicon glyphicon-text-width" aria-hidden="true"></span>
  226. <p class="glyphicon-class">自定义</p>
  227. </a>
  228. </div>
  229. </a-col>
  230. </a-row>
  231. <a-row class="drag_item_title">辅助</a-row>
  232. <a-row style="height: 100px;">
  233. <a-col :span="12" class="drag_item_box">
  234. <div>
  235. <a class="ep-draggable-item" tid="defaultModule.hline" style>
  236. <span class="glyphicon glyphicon-resize-horizontal" aria-hidden="true"></span>
  237. <p class="glyphicon-class">横线</p>
  238. </a>
  239. </div>
  240. </a-col>
  241. <a-col :span="12" class="drag_item_box">
  242. <div>
  243. <a class="ep-draggable-item" tid="defaultModule.vline" style>
  244. <span class="glyphicon glyphicon-resize-vertical" aria-hidden="true"></span>
  245. <p class="glyphicon-class">竖线</p>
  246. </a>
  247. </div>
  248. </a-col>
  249. </a-row>
  250. <a-row style="height: 100px;">
  251. <a-col :span="12" class="drag_item_box">
  252. <div>
  253. <a class="ep-draggable-item" tid="defaultModule.rect">
  254. <span class="glyphicon glyphicon-unchecked" aria-hidden="true"></span>
  255. <p class="glyphicon-class">矩形</p>
  256. </a>
  257. </div>
  258. </a-col>
  259. <a-col :span="12" class="drag_item_box">
  260. <div>
  261. <a class="ep-draggable-item" tid="defaultModule.oval">
  262. <span class="glyphicon glyphicon-record" aria-hidden="true"></span>
  263. <p class="glyphicon-class">椭圆</p>
  264. </a>
  265. </div>
  266. </a-col>
  267. </a-row>
  268. <a-row v-if="currVerInfo.verVal >= 55.3" style="height: 100px;">
  269. <a-col :span="12" class="drag_item_box">
  270. <div>
  271. <a class="ep-draggable-item" tid="defaultModule.barcode">
  272. <span class="glyphicon glyphicon-barcode" aria-hidden="true"></span>
  273. <p class="glyphicon-class">条形码</p>
  274. </a>
  275. </div>
  276. </a-col>
  277. <a-col :span="12" class="drag_item_box">
  278. <div>
  279. <a class="ep-draggable-item" tid="defaultModule.qrcode">
  280. <span class="glyphicon glyphicon-qrcode" aria-hidden="true"></span>
  281. <p class="glyphicon-class">二维码</p>
  282. </a>
  283. </div>
  284. </a-col>
  285. </a-row>
  286. </a-col>
  287. </a-row>
  288. </a-card>
  289. </a-col>
  290. <a-col :span="15">
  291. <a-card class="card-design">
  292. <div id="hiprint-printTemplate" class="hiprint-printTemplate"></div>
  293. </a-card>
  294. </a-col>
  295. <a-col :span="5" class="params_setting_container">
  296. <a-card>
  297. <a-row class="hinnn-layout-sider">
  298. <div id="PrintElementOptionSetting"></div>
  299. </a-row>
  300. </a-card>
  301. </a-col>
  302. </a-row>
  303. <!-- 预览 -->
  304. <print-preview ref="preView"/>
  305. <a-modal v-model="showName" title="模板名称" @ok="saveTemplate" @cancel="cancelCaveTemplate" okText="确定" cancelText="取消" :confirmLoading="loading">
  306. <a-input v-model="templateName" placeholder="请输入模板名称" />
  307. </a-modal>
  308. </a-card>
  309. </template>
  310. <script defer>
  311. // import {defaultElementTypeProvider, hiprint} from '../../index'
  312. import { saveAndEdit,selectById } from '@/api/printdesign/printdesign'
  313. import * as vuePluginHiprint from '../../../index'
  314. // import panel from './panel'
  315. import printData from './print-data'
  316. import printPreview from './preview'
  317. import jsonView from "../json-view.vue";
  318. import fontSize from "./font-size.js";
  319. import scale from "./scale.js";
  320. import { decodeVer } from '@/utils'
  321. // disAutoConnect();
  322. var hiprint, defaultElementTypeProvider, panel;
  323. let hiprintTemplate;
  324. export default {
  325. name: "printDesign",
  326. components: {printPreview, jsonView},
  327. data() {
  328. return {
  329. showName:false,
  330. templateName:'',
  331. loading:false,
  332. panelsData:null,
  333. template: null,
  334. curPaper: {
  335. type: 'A4',
  336. width: 210,
  337. height: 296.6
  338. },
  339. paperTypes: {
  340. 'A3': {
  341. width: 420,
  342. height: 296.6
  343. },
  344. 'A4': {
  345. width: 210,
  346. height: 296.6
  347. },
  348. 'A5': {
  349. width: 210,
  350. height: 147.6
  351. },
  352. 'B3': {
  353. width: 500,
  354. height: 352.6
  355. },
  356. 'B4': {
  357. width: 250,
  358. height: 352.6
  359. },
  360. 'B5': {
  361. width: 250,
  362. height: 175.6
  363. }
  364. },
  365. // 自定义纸张
  366. paperPopVisible: false,
  367. paperWidth: '220',
  368. paperHeight: '80',
  369. // 缩放
  370. scaleValue: 1,
  371. scaleMax: 5,
  372. scaleMin: 0.5,
  373. // 导入导出json
  374. jsonIn: '',
  375. jsonOut: '',
  376. }
  377. },
  378. computed: {
  379. curPaperType() {
  380. let type = 'other'
  381. let types = this.paperTypes
  382. for (const key in types) {
  383. let item = types[key]
  384. let {width, height} = this.curPaper
  385. if (item.width === width && item.height === height) {
  386. type = key
  387. }
  388. }
  389. return type
  390. },
  391. /**
  392. * @description: 当前版本信息,用于 demo 页面根据版本控制功能
  393. * @return {Object}
  394. */
  395. currVerInfo() {
  396. if (this.$parent.version && this.$parent.version != "development") {
  397. return decodeVer(this.$parent.version)
  398. } else if (hiprint?.version) {
  399. return decodeVer(hiprint.version)
  400. } else {
  401. return {
  402. verVal: 9999
  403. }
  404. }
  405. }
  406. },
  407. mounted() {
  408. const templateId = this.$route.query.id;
  409. if(templateId){
  410. this.getTemplate(templateId)
  411. }else{
  412. this.templateName = '';
  413. }
  414. this.getPanel()
  415. // 存在一个固定版本号,并且不是开发版本
  416. if (this.$parent.version && this.$parent.version != "development") {
  417. // 加载对应版本的 hiprint
  418. this.getVersion(this.$parent.version)
  419. }
  420. // 不存在固定版本,加载当前代码中的 hiprint
  421. else {
  422. hiprint = vuePluginHiprint.hiprint
  423. defaultElementTypeProvider = vuePluginHiprint.defaultElementTypeProvider
  424. this.init()
  425. }
  426. },
  427. methods: {
  428. /**
  429. * @description: 加载 panel
  430. */
  431. getPanel() {
  432. // 加载所有 panel
  433. const panels = require.context('./', true, /panel.*\.js$/)
  434. // 对所有 panel 进行版本解析
  435. var panelInfos = panels.keys().map(key => ({
  436. ...decodeVer(key.replace(/(\.\/panel-?)|(\.js)/g, '')),
  437. key
  438. }))
  439. // 存在一个固定版本号,并且不是开发版本
  440. if (this.$parent.version && this.$parent.version != "development") {
  441. // 解析对应版本信息
  442. var currVerInfo = decodeVer(this.$parent.version)
  443. // 查找小于等于当前版本的 panel
  444. var newVers = panelInfos.filter(({verVal}) => verVal <= currVerInfo.verVal)
  445. // 对版本号进行倒叙
  446. .sort((acc, curr) => curr.verVal - acc.verVal)
  447. // 获取最大版本号面板 json
  448. panel = panels(newVers[0].key).default
  449. }
  450. // 不存在固定版本,加载默认面板 json
  451. else {
  452. panel = panels('./panel.js').default
  453. }
  454. },
  455. setPanel(){
  456. // console.log('panelsData',this.panelsData);
  457. panel = this.panelsData;
  458. this.init()
  459. },
  460. /**
  461. * @description: 加载版本
  462. * @param {string} version 版本号
  463. */
  464. getVersion(version) {
  465. const script = document.createElement("script");
  466. script.setAttribute("type", "text/javascript");
  467. script.setAttribute(
  468. "src",
  469. `https://cdn.jsdelivr.net/npm/vue-plugin-hiprint@${version}/dist/vue-plugin-hiprint.js`
  470. );
  471. script.addEventListener("load", () => {
  472. hiprint = window['vue-plugin-hiprint'].hiprint
  473. defaultElementTypeProvider = window['vue-plugin-hiprint'].defaultElementTypeProvider
  474. this.init()
  475. })
  476. document.body.append(script)
  477. },
  478. init() {
  479. hiprint.init({
  480. providers: [new defaultElementTypeProvider()],
  481. lang: this.$parent.lang
  482. });
  483. // 还原配置
  484. hiprint.setConfig()
  485. // 替换配置
  486. hiprint.setConfig({
  487. optionItems: [
  488. fontSize,
  489. scale,
  490. function () {
  491. function t() {
  492. this.name = "zIndex";
  493. }
  494. return t.prototype.css = function (t, e) {
  495. if (t && t.length) {
  496. if (e) return t.css('z-index', e);
  497. }
  498. return null;
  499. }, t.prototype.createTarget = function () {
  500. return this.target = $('<div class="hiprint-option-item">\n <div class="hiprint-option-item-label">\n 元素层级2\n </div>\n <div class="hiprint-option-item-field">\n <input type="number" class="auto-submit"/>\n </div>\n </div>'), this.target;
  501. }, t.prototype.getValue = function () {
  502. var t = this.target.find("input").val();
  503. if (t) return parseInt(t.toString());
  504. }, t.prototype.setValue = function (t) {
  505. this.target.find("input").val(t);
  506. }, t.prototype.destroy = function () {
  507. this.target.remove();
  508. }, t;
  509. }(),
  510. ],
  511. movingDistance: 2.5,
  512. text: {
  513. tabs: [
  514. // 隐藏部分
  515. {
  516. // name: '测试', // tab名称 可忽略
  517. options: [] // 必须包含 options
  518. },// 当修改第二个 tabs 时,必须把他之前的 tabs 都列举出来.
  519. {
  520. name: '样式', options: [
  521. {
  522. name: 'scale',
  523. after: 'transform', // 自定义参数,插入在 transform 之后
  524. hidden: false
  525. },
  526. ]
  527. }
  528. ],
  529. supportOptions: [
  530. {
  531. name: 'styler',
  532. hidden: true
  533. },
  534. {
  535. name: 'scale', // 自定义参数,supportOptions 必须得添加
  536. after: 'transform', // 自定义参数,插入在 transform 之后
  537. hidden: false
  538. },
  539. {
  540. name: 'formatter',
  541. hidden: true
  542. },
  543. ]
  544. },
  545. image: {
  546. tabs: [
  547. {
  548. // 整体替换
  549. replace: true,
  550. name: '基本', options: [
  551. {
  552. name: 'field',
  553. hidden: false
  554. },
  555. {
  556. name: 'src',
  557. hidden: false
  558. },
  559. {
  560. name: 'fit',
  561. hidden: false
  562. }
  563. ]
  564. },
  565. ],
  566. }
  567. })
  568. // eslint-disable-next-line no-undef
  569. hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'));
  570. $('#hiprint-printTemplate').empty()
  571. let that = this;
  572. this.template = hiprintTemplate = new hiprint.PrintTemplate({
  573. template: panel,
  574. // 图片选择功能
  575. onImageChooseClick: (target) => {
  576. // 测试 3秒后修改图片地址值
  577. setTimeout(() => {
  578. // target.refresh(url,options,callback)
  579. // callback(el, width, height) // 原元素,宽,高
  580. // target.refresh(url,false,(el,width,height)=>{
  581. // el.options.width = width;
  582. // el.designTarget.css('width', width + "pt");
  583. // el.designTarget.children('.resize-panel').trigger($.Event('click'));
  584. // })
  585. target.refresh("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtAAAAIIAQMAAAB99EudAAAABlBMVEUmf8vG2O41LStnAAABD0lEQVR42u3XQQqCQBSAYcWFS4/QUTpaHa2jdISWLUJjjMpclJoPGvq+1WsYfiJCZ4oCAAAAAAAAAAAAAAAAAHin6pL9c6H/fOzHbRrP0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0u/SY9LS0tLS0tLS0tLS0n+edm+UlpaWlpaWlpaWlpaW/tl0Ndyzbno7/+tPTJdd1wal69dNa6abx+Lq6TSeYtK7BX/Diek0XULSZZrakPRtV0i6Hu/KIt30q4fM0pvBqvR9mvsQkZaW9gyJT+f5lsnzjR54xAk8mAUeJyMPwYFH98ALx5Jr0kRLLndT7b64UX9QR/0eAAAAAAAAAAAAAAAAAAD/4gpryzr/bja4QgAAAABJRU5ErkJggg==", {
  586. // auto: true, // 根据图片宽高自动等比(宽>高?width:height)
  587. // width: true, // 按宽调整高
  588. // height: true, // 按高调整宽
  589. real: true // 根据图片实际尺寸调整(转pt)
  590. })
  591. }, 3000)
  592. // target.getValue()
  593. // target.refresh(url)
  594. },
  595. // 自定义可选字体
  596. // 或者使用 hiprintTemplate.setFontList([])
  597. // 或元素中 options.fontList: []
  598. fontList: [
  599. {title: '微软雅黑', value: 'Microsoft YaHei'},
  600. {title: '黑体', value: 'STHeitiSC-Light'},
  601. {title: '思源黑体', value: 'SourceHanSansCN-Normal'},
  602. {title: '王羲之书法体', value: '王羲之书法体'},
  603. {title: '宋体', value: 'SimSun'},
  604. {title: '华为楷体', value: 'STKaiti'},
  605. {title: 'cursive', value: 'cursive'},
  606. ],
  607. dataMode: 1, // 1:getJson 其他:getJsonTid 默认1
  608. history: true, // 是否需要 撤销重做功能
  609. onDataChanged: (type, json) => {
  610. console.log(type); // 新增、移动、删除、修改(参数调整)、大小、旋转
  611. console.log(json); // 返回 template
  612. },
  613. onUpdateError: (e) => {
  614. console.log(e);
  615. },
  616. settingContainer: '#PrintElementOptionSetting',
  617. paginationContainer: '.hiprint-printPagination'
  618. });
  619. hiprintTemplate.design('#hiprint-printTemplate', {grid: true});
  620. // 获取当前放大比例, 当zoom时传true 才会有
  621. this.scaleValue = hiprintTemplate.editingPanel.scale || 1;
  622. },
  623. /**
  624. * 设置纸张大小
  625. * @param type [A3, A4, A5, B3, B4, B5, other]
  626. * @param value {width,height} mm
  627. */
  628. setPaper(type, value) {
  629. try {
  630. if (Object.keys(this.paperTypes).includes(type)) {
  631. this.curPaper = {type: type, width: value.width, height: value.height}
  632. hiprintTemplate.setPaper(value.width, value.height)
  633. } else {
  634. this.curPaper = {type: 'other', width: value.width, height: value.height}
  635. hiprintTemplate.setPaper(value.width, value.height)
  636. }
  637. } catch (error) {
  638. this.$message.error(`操作失败: ${error}`)
  639. }
  640. },
  641. otherPaper() {
  642. let value = {}
  643. value.width = this.paperWidth
  644. value.height = this.paperHeight
  645. this.paperPopVisible = false
  646. this.setPaper('other', value)
  647. },
  648. changeScale(big) {
  649. let scaleValue = this.scaleValue;
  650. if (big) {
  651. scaleValue += 0.1;
  652. if (scaleValue > this.scaleMax) scaleValue = 5;
  653. } else {
  654. scaleValue -= 0.1;
  655. if (scaleValue < this.scaleMin) scaleValue = 0.5;
  656. }
  657. if (hiprintTemplate) {
  658. // scaleValue: 放大缩小值, false: 不保存(不传也一样), 如果传 true, 打印时也会放大
  659. hiprintTemplate.zoom(scaleValue);
  660. this.scaleValue = scaleValue;
  661. }
  662. },
  663. rotatePaper() {
  664. if (hiprintTemplate) {
  665. hiprintTemplate.rotatePaper()
  666. }
  667. },
  668. preView() {
  669. // 测试, 点预览更新拖拽元素
  670. hiprint.updateElementType('defaultModule.text', (type) => {
  671. type.title = '这是更新后的元素';
  672. return type
  673. })
  674. // 测试, 通过socket刷新打印机列表; 默认只有连接的时候才会获取到最新的打印机列表
  675. hiprint.refreshPrinterList((list) => {
  676. console.log('refreshPrinterList')
  677. console.log(list)
  678. });
  679. // 测试, 获取IP、IPV6、MAC地址、DNS
  680. // 参数格式:
  681. // 1. 类型(ip、ipv6、mac、dns、all、interface、vboxnet)
  682. // 2. 回调 data => {addr, e} addr: 返回的数据 e:错误信息
  683. // 3. 其他参数 ...args
  684. hiprint.getAddress('ip', (data) => {
  685. console.log('ip')
  686. console.log(data)
  687. })
  688. hiprint.getAddress('ipv6', (data) => {
  689. console.log('ipv6')
  690. console.log(data)
  691. })
  692. hiprint.getAddress('mac', (data) => {
  693. console.log('mac')
  694. console.log(data)
  695. })
  696. hiprint.getAddress('dns', (data) => {
  697. console.log('dns')
  698. console.log(data)
  699. })
  700. hiprint.getAddress('all', (data) => {
  701. console.log('all')
  702. console.log(data)
  703. })
  704. // 各个平台不一样, 用法见: https://www.npmjs.com/package/address
  705. hiprint.getAddress('interface', (data) => {
  706. console.log('interface')
  707. console.log(data)
  708. }, 'IPv4', 'eth1')
  709. this.$refs.preView.show(hiprintTemplate, printData)
  710. },
  711. onlyPrint() {
  712. let hiprintTemplate = this.$print(undefined, panel, printData, {}, {
  713. styleHandler: () => {
  714. let css = '<link href="http://hiprint.io/Content/hiprint/css/print-lock.css" media="print" rel="stylesheet">';
  715. return css
  716. }
  717. })
  718. console.log(hiprintTemplate);
  719. },
  720. onlyPrint2() {
  721. let that = this;
  722. if (window.hiwebSocket.opened) {
  723. let hiprintTemplate = this.$print2(undefined, panel, printData, {
  724. printer: '', title: 'Api单独打印',
  725. styleHandler: () => {
  726. // let css = '<link href="http://hiprint.io/Content/hiprint/css/print-lock.css" media="print" rel="stylesheet">';
  727. let css = '<style>.hiprint-printElement-text{color:red !important;}</style>'
  728. return css
  729. }
  730. })
  731. let key = 'Api单独直接打印';
  732. hiprintTemplate.on('printSuccess', function () {
  733. that.$notification.success({
  734. key: key,
  735. placement: 'topRight',
  736. message: key + ' 打印成功',
  737. description: 'Api单独直接打印回调',
  738. });
  739. });
  740. return;
  741. }
  742. this.$error({
  743. title: "客户端未连接",
  744. content: (h) => (
  745. <div>
  746. 连接【{hiwebSocket.host}】失败!
  747. <br />
  748. 请确保目标服务器已
  749. <a
  750. href="https://gitee.com/CcSimple/electron-hiprint/releases"
  751. target="_blank"
  752. >
  753. 下载
  754. </a>
  755. <a href="hiprint://" target="_blank">
  756. 运行
  757. </a>
  758. 打印服务!
  759. </div>
  760. ),
  761. });
  762. },
  763. print() {
  764. if (window.hiwebSocket.opened) {
  765. const printerList = hiprintTemplate.getPrinterList();
  766. console.log(printerList)
  767. hiprintTemplate.print2(printData, {printer: '', title: 'hiprint测试打印'});
  768. return
  769. }
  770. this.$error({
  771. title: "客户端未连接",
  772. content: (h) => (
  773. <div>
  774. 连接【{hiwebSocket.host}】失败!
  775. <br />
  776. 请确保目标服务器已
  777. <a
  778. href="https://gitee.com/CcSimple/electron-hiprint/releases"
  779. target="_blank"
  780. >
  781. 下载
  782. </a>
  783. <a href="hiprint://" target="_blank">
  784. 运行
  785. </a>
  786. 打印服务!
  787. </div>
  788. ),
  789. });
  790. },
  791. clearPaper() {
  792. try {
  793. hiprintTemplate.clear();
  794. } catch (error) {
  795. this.$message.error(`操作失败: ${error}`);
  796. }
  797. },
  798. exportPdf(type) {
  799. hiprintTemplate.toPdf(printData, '测试导出pdf', {isDownload: false, type: type}).then((res) => {
  800. console.log('type:', type);
  801. console.log(res);
  802. });
  803. },
  804. ippPrintAttr() {
  805. // 不知道打印机 ipp 情况, 可通过 '客户端' 获取一下
  806. const printerList = hiprintTemplate.getPrinterList();
  807. console.log(printerList)
  808. if (!printerList.length) return;
  809. let p = printerList[0];
  810. console.log(p)
  811. // 系统不同, 参数可能不同
  812. let url = p.options['printer-uri-supported'];
  813. // 测试 获取 ipp打印 支持参数
  814. hiprint.ippPrint({
  815. url: url,
  816. // 打印机参数: {version,uri,charset,language}
  817. opt: {},
  818. action: 'Get-Printer-Attributes', // 获取打印机支持参数
  819. // ipp参数
  820. message: null,
  821. }, (res) => {
  822. // 执行的ipp 任务回调 / 错误回调
  823. console.log(res)
  824. }, (printer) => {
  825. // ipp连接成功 回调 打印机信息
  826. console.log(printer)
  827. })
  828. },
  829. ippPrintTest() {
  830. // 不知道打印机 ipp 情况, 可通过 '客户端' 获取一下
  831. const printerList = hiprintTemplate.getPrinterList();
  832. console.log(printerList)
  833. if (!printerList.length) return;
  834. let p = printerList[0];
  835. console.log(p)
  836. // 系统不同, 参数可能不同
  837. let url = p.options['printer-uri-supported'];
  838. // 测试 打印文本
  839. hiprint.ippPrint({
  840. url: url,
  841. // 打印机参数: {version,uri,charset,language}
  842. opt: {},
  843. action: 'Print-Job',
  844. // ipp参数
  845. message: {
  846. "operation-attributes-tag": {
  847. "requesting-user-name": "hiPrint", // 用户名
  848. "job-name": "ipp Test Job", // 任务名
  849. "document-format": "text/plain" // 文档类型
  850. },
  851. // data 需为 Buffer (客户端简单处理了string 转 Buffer), 支持设置 encoding
  852. // data 需为 Buffer (客户端简单处理了string 转 Buffer), 支持设置 encoding
  853. // data 需为 Buffer (客户端简单处理了string 转 Buffer), 支持设置 encoding
  854. // 其他 Uint8Array/ArrayBuffer 默认仅 使用 Buffer.from(data)
  855. // 其他 Uint8Array/ArrayBuffer 默认仅 使用 Buffer.from(data)
  856. // 其他 Uint8Array/ArrayBuffer 默认仅 使用 Buffer.from(data)
  857. // 其他 Uint8Array/ArrayBuffer 默认仅 使用 Buffer.from(data)
  858. data: 'test test test test test test test',
  859. encoding: 'utf-8' // 默认可不传
  860. }
  861. }, (res) => {
  862. // 执行的ipp 任务回调 / 错误回调
  863. console.log(res)
  864. }, (printer) => {
  865. // ipp连接成功 回调 打印机信息
  866. console.log(printer)
  867. })
  868. },
  869. // 自定义 ipp 请求
  870. ippRequestTest() {
  871. const printerList = hiprintTemplate.getPrinterList();
  872. console.log(printerList)
  873. if (!printerList.length) return;
  874. let p = printerList[0];
  875. console.log(p)
  876. // 系统不同, 参数可能不同
  877. let url = p.options['printer-uri-supported'];
  878. // 详见: https://www.npmjs.com/package/ipp
  879. hiprint.ippRequest({
  880. url: url,
  881. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  882. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  883. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  884. data: {
  885. "operation": "Get-Printer-Attributes",
  886. "operation-attributes-tag": {
  887. // 测试发现 Request下列3个必须要有
  888. "attributes-charset": "utf-8",
  889. "attributes-natural-language": "zh-cn",
  890. "printer-uri": url
  891. }
  892. }
  893. }, (res) => {
  894. // 执行的ipp 任务回调 / 错误回调
  895. console.log(res)
  896. })
  897. },
  898. ippRequestPrint() {
  899. const printerList = hiprintTemplate.getPrinterList();
  900. console.log(printerList)
  901. if (!printerList.length) return;
  902. let p = printerList[0];
  903. console.log(p)
  904. // 系统不同, 参数可能不同
  905. let url = p.options['printer-uri-supported'];
  906. let str = "ippRequestPrint ippRequestPrint ippRequestPrint";
  907. let array = new Uint8Array(str.length);
  908. for (var i = 0; i < str.length; i++) {
  909. array[i] = str.charCodeAt(i);
  910. }
  911. let testData = array.buffer;
  912. // 详见: https://www.npmjs.com/package/ipp
  913. hiprint.ippRequest({
  914. url: url,
  915. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  916. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  917. // 传入的数据 ipp.serialize 后 未做任何处理 打印内容 需要 Buffer
  918. data: {
  919. "operation": "Print-Job",
  920. "operation-attributes-tag": {
  921. // 测试发现 Request下列3个必须要有
  922. "attributes-charset": "utf-8",
  923. "attributes-natural-language": "zh-cn",
  924. "printer-uri": url,
  925. "requesting-user-name": "hiPrint", // 用户名
  926. "job-name": "ipp Request Job", // 任务名
  927. "document-format": "text/plain" // 文档类型
  928. },
  929. data: testData
  930. }
  931. }, (res) => {
  932. // 执行的ipp 任务回调 / 错误回调
  933. console.log(res)
  934. })
  935. },
  936. updateJson() {
  937. if (hiprintTemplate) {
  938. try {
  939. hiprintTemplate.update(JSON.parse(this.jsonIn))
  940. } catch (e) {
  941. this.$message.error(`更新失败: ${e}`)
  942. }
  943. }
  944. },
  945. exportJson() {
  946. if (hiprintTemplate) {
  947. this.jsonOut = JSON.stringify(hiprintTemplate.getJson() || {})
  948. console.log('this.jsonOut',this.jsonOut);
  949. }
  950. },
  951. setElsAlign(e) {
  952. hiprintTemplate.setElsAlign(e)
  953. },
  954. setElsSpace(h) {
  955. hiprintTemplate.setElsSpace(10, h)
  956. },
  957. getSelectEls() {
  958. let els = hiprintTemplate.getSelectEls();
  959. console.log(els)
  960. },
  961. updateFontSize() {
  962. hiprintTemplate.updateOption('fontSize', 12);
  963. },
  964. updateFontWeight() {
  965. hiprintTemplate.updateOption('fontWeight', 'bolder');
  966. },
  967. // 新增的
  968. getTemplate(templateId){
  969. selectById(templateId).then(res=>{
  970. this.templateName = res.data.name;
  971. this.jsonIn=res.data.content;
  972. this.panelsData=res.data.contentJson;
  973. this.setPanel();
  974. this.updateJson();
  975. }).catch(err=>{
  976. console.log('getTemplate err',err);
  977. })
  978. },
  979. cancelCaveTemplate(){
  980. this.showName=false;
  981. // this.templateName = '';
  982. },
  983. saveTemplate(){
  984. if (hiprintTemplate) {
  985. // console.log('hiprintTemplate=====',hiprintTemplate);
  986. this.loading = true;
  987. let josnData = JSON.stringify(hiprintTemplate.getJson() || {})
  988. // console.log('josnData',josnData);
  989. let params = {
  990. name:this.templateName,
  991. contentJson:josnData
  992. }
  993. saveAndEdit(params).then(res => {
  994. if (res.code === 200) {
  995. this.$message.success("操作成功!");
  996. this.cancelCaveTemplate();
  997. }
  998. }).catch(error => {
  999. console.log('saveTemplate error',error)
  1000. }).finally(() => {
  1001. this.loading = false;
  1002. })
  1003. }
  1004. }
  1005. }
  1006. }
  1007. </script>
  1008. <style lang="less" scoped>
  1009. // 拖拽
  1010. .drag_item_box {
  1011. height: 100%;
  1012. padding: 6px;
  1013. }
  1014. .drag_item_box > div {
  1015. height: 100%;
  1016. width: 100%;
  1017. background-color: #fff;
  1018. display: flex;
  1019. justify-content: center;
  1020. align-items: center;
  1021. }
  1022. .drag_item_box > div > a {
  1023. text-align: center;
  1024. text-decoration-line: none;
  1025. }
  1026. .drag_item_box > div > a > span {
  1027. font-size: 28px;
  1028. }
  1029. .drag_item_box > div > a > p {
  1030. margin: 0;
  1031. }
  1032. .drag_item_title {
  1033. font-size: 16px;
  1034. padding: 12px 6px 0 6px;
  1035. font-weight: bold;
  1036. }
  1037. // 默认图片
  1038. /deep/ .hiprint-printElement-image-content {
  1039. img {
  1040. content: url("~@/assets/logo.png");
  1041. }
  1042. }
  1043. // 辅助线样式
  1044. /deep/ .toplineOfPosition {
  1045. border: 0;
  1046. border-top: 1px dashed purple;
  1047. }
  1048. /deep/ .bottomlineOfPosition {
  1049. border: 0;
  1050. border-top: 1px dashed purple;
  1051. }
  1052. /deep/ .leftlineOfPosition {
  1053. border: 0;
  1054. border-left: 1px dashed purple;
  1055. }
  1056. /deep/ .rightlineOfPosition {
  1057. border: 0;
  1058. border-left: 1px dashed purple;
  1059. }
  1060. // 设计容器
  1061. .card-design {
  1062. overflow: hidden;
  1063. overflow-x: auto;
  1064. overflow-y: auto;
  1065. }
  1066. .pagetop{
  1067. text-align: center;
  1068. margin-bottom: 20px;
  1069. .templateName{font-size: 18px;font-weight: 500;margin-bottom: 10px;}
  1070. .tip{font-size: 14px;color:crimson;}
  1071. }
  1072. </style>