vue + Lodop 制作可视化设计页面 实现打印设计功能(四)

历史:

vue2 + Lodop 制作可视化设计页面 实现打印设计功能(一)

vue + Lodop 制作可视化设计页面 实现打印设计功能(二)

vue + Lodop 制作可视化设计页面 实现打印设计功能(三)

前言:

在上篇文章我们已经简单的实现了一个自定义控件HPText,在这篇我们来引入lodop实现打印预览

主要技术栈:vue3+vite+pinia+less+typescript

目录:

  1. 项目创建及模块定义,简单实现拖拽新增
  2. 新增第一个自定义组件-HPText(文本组件)
  3. 引入lodop,打印预览
  4. 组件点击拖拽移动
  5. 新增HPText组件的菜单,组件菜单设置时组件动态变化
  6. 框选组件,批量移动
  7. 待定...

正文:

要引入lodop,首先需要引入pinia,也就是需要把page信息以及com组件信息存在store中,之后写一个解析page信息的解析工具方法即可

引入pinia

  • 定义comStore

在这个里面定义3个方法 :初始化page,初始化组件列表,添加组件

TypeScript 复制代码
import {defineStore} from 'pinia'
import {IOptionItem, IPage} from "../domains/qy-component.ts";
import {createComponent} from "../components/tool.ts";

export interface IComState {
    page: IPage,
    optionItems: IOptionItem[]
}

export const useComStore = defineStore('com', {
    state: (): IComState => ({
        page: {},
        optionItems: []
    }),
    getters: {},
    actions: {
        initPage(pageInfo: IPage) {
            this.page = pageInfo
        },
        initOptionItems(options: IOptionItem) {
            this.optionItems = options
        },
        async add(index, x, y) {
            let com = await createComponent(this.optionItems[index].type)
            com.attr.x = x;
            com.attr.y = y;
            this.page.tempItems.push({
                ...com,
                ...this.optionItems[index]
            })
        }
    }
})
  • 改造viewport.index.vue

主要是把之前的dropToAddCom函数改成调用 useComStore 的add方法,页面上渲染的page以及com从useComStore 中通过 computed获取

TypeScript 复制代码
const comStore = useComStore()
const widget = computed(() => comStore.page.tempItems)
const page = computed(() => comStore.page)

const dropToAddCom = async (ev:DragEvent) => {
  ev.preventDefault()
  let index = ev.dataTransfer.getData('index')
  const rest = edit.value.getBoundingClientRect();
  await comStore.add(
      index,
      Math.round(ev.clientX - rest.x),
      Math.round(ev.clientY - rest.y)
  )
}
  • 在app.vue 初始化数据
TypeScript 复制代码
const comStore = useComStore()

onMounted(()=>{
  //初始化数据
  comStore.initPage({
    title: 'demo',
    width: 566,
    height: 377,
    pageWidth: 150,
    pageHeight: 100,
    tempItems: []
  })
  comStore.initOptionItems(datas)
})

引入lodop

  • 在lodop官网下载 驱动

把其中的LodopFuncs.js 放入代码

  • 定义工具方法

主要功能是解析page的内容,生成Lodop代码执行

TypeScript 复制代码
import getLodop from './LodopFuncs.js'
import {IPage, QYComponent} from "../domains/qy-component.ts";
import {createComHtml} from "../components/tool.ts";

export default {preview}

let strCompanyName = ''
let strLicense = ''
let strLicenseA = ''
let strLicenseB = ''

/**
 * 打印预览功能
 * @param {*Object} template 打印模板
 * @param {*Array} data 打印数据
 */
async function preview(template: IPage, data) {
    let LODOP = _createLodop(template.title, template.width, template.height, template.pageWidth, template.pageHeight)
    let tempItems = [...template.tempItems]
    if (data.length > 1) {
        // 打印多份
        for (let i = 0; i < data.length; i++) {
            LODOP.NewPageA()
            for (let index = 0; index < tempItems.length; index++) {
                await _addPrintItem(LODOP, tempItems[index], data[i])
            }
        }
    } else {
        // 单份
        for (let index = 0; index < tempItems.length; index++) {
            await _addPrintItem(LODOP, tempItems[index], data[0])
        }
    }
    LODOP.PREVIEW()
}

async function _addPrintItem(LODOP:any, printItem: QYComponent, data:any) {
    await createComHtml(printItem, data, LODOP);
    LODOP.SET_PRINT_STYLEA(0, "ItemType", printItem.itemType);
}


function _createLodop(pageName, width, height, pageWidth = 0, pageHeight = 0, top = 0, left = 0) {
    let LODOP = getLodop()
    // 设置软件产品注册信息
    LODOP.SET_LICENSES(strCompanyName, strLicense, strLicenseA, strLicenseB)
    LODOP.PRINT_INITA(top, left, width, height, pageName)
    LODOP.SET_PRINT_PAGESIZE(1, pageWidth ? pageWidth + 'mm' : 0, pageHeight ? pageHeight + 'mm' : 0, '')
    return LODOP
}
  • 定义HPText解析方法

首先在QYComponent 中定义一个 抽象函数 generatePrint

然后在HPText 中 实现 此函数

TypeScript 复制代码
   generatePrint(LODOP, item, data){
        let html = this.toHtml(item, data);
        LODOP.ADD_PRINT_HTM(
            item.attr.y,
            item.attr.x,
            item.attr.width,
            item.attr.height,
            html
        )
    }

    toHtml(item, data):string{
        let txt = item.title;
        return `
            <div style="
              word-break:break-all;
              overflow: hidden;
              display: flex;
              font-size: 12pt;
              width: ${item.attr.width}px;
              height:${item.attr.height}px;
              white-space:pre-wrap;">${txt}</div>`;
    }

至此就实现了引入lodop 并预览

细心的可能发现了解析的方法里存在一个data参数,这个参数其实用于动态解析加载内容的,在toHtml中通过data以及item生成对应txt即可。

效果

demo示例

相关推荐
GIS程序媛—椰子6 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00112 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端15 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100919 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439129 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt