Как добиться максимально реалистичной веб-печати
Компания организовала медицинское обследование.В больнице было обнаружено, что удостоверение личности можно использовать для быстрой печати формы медицинского осмотра, что было очень удобно.Однако после более тщательного изучения эффект печати был крайне плохим.
статус-кво
Примечание: Если напрямую вызвать Ctrl+P, то он напечатает текущий вьюпорт, можно выбрать принтер и бумагу для принтера, что явно не соответствует бизнес-требованиям, если вызвать window.print(), то можно писать css только на html и загрузите его вместе на принтер, а принтер, бумагу и другие параметры нельзя предварительно установить, а шаблон нельзя сохранить. Пролистав большую часть отпечатков, они вызывают для этого функцию window.print(), но есть некоторые проблемы:
-
打印样式、排版问题。
Стиль печати отличается от написания в браузере.Набор css пишется на дисплее страницы, а набор css также пишется в html-строке, передаваемой на принтер, и не совместим со всеми бумагами. -
无法限定预设打印机、打印机纸张及保存为模板。
Использование ActiveX (только под IE) явно не соответствует бизнес-требованиям.
Используйте Websocket, чтобы установить соединение с аппаратом, чтобы получить информацию о печати аппарата. -
自定义纸张问题。
Не могу сделать нестандартную бумагу. -
浏览器显示与打印结果不一致。
Это самая распространенная и актуальная проблема, требующая решения.
Так получилось, что мне нужно было сделать функцию печати, поэтому я решил провести рефакторинг для решения вышеуказанных проблем. Я принял вторую схему и интегрировал облачную печать PAZU, используя исполняемый скрипт, разработанный на C++, для подключения к собственному Websocket для возврата информации о печати во время выполнения. Для учащихся, которым необходимо знать больше, перейдите по ссылке:Официальный сайт PAZU
эффект печати
Результаты печати, как правило, являются реальными отпечатками после тестирования, что почти идентично веб-отображению.
распечатать идеи
Общая идея состоит в том, чтобы визуализировать и настроить параметры устройства печати, которые можно предварительно настроить для передачи на устройство печати при нажатии кнопки печати. Если настройка не поддерживается, сначала выполните синхронизацию с принтером, а затем выберите.
настройки шаблона печати
1. Получить данные для печати
Типичная страница ERP сведений, включая основную форму таблицы и детали таблицы подставки
1. Получить форму
GetSlideInfo () {
let CondiData = []
let SlideInfoVnode = this.$refs.SlideInfo.$children[0]
let FormItems = findComponentsDownward(SlideInfoVnode, 'FormItem')
FormItems.forEach((item, itemIndex) => {
let field = item.$children
if (field.length) {
const fieldVnode = item.$children[0]
let fieldValue = this.GetExportFieldValue(fieldVnode)
let formItem = {
key: item.prop,
label: item.label.split(':')[0],
value: fieldValue,
index: itemIndex
}
Object.assign(formItem, fieldVnode.print)
CondiData.push(formItem)
}
})
return CondiData
}
использоватьfindComponentsDownwardполучить всеFormItem, затем получитьFormItemиз
VueComponment, Получить информацию о печати в экземпляре компонента.
Для поддержки пакетной печати деталей списковv-print:
import { typeOf } from '@/libs/util'
export default {
inserted: (el, { value, arg }, vnode) => {
if (!value) return
if (typeOf(value) != 'object') value = {}
vnode.componentInstance.print = Object.assign(value, { renderType: arg || 'input' })
},
update: (el, { value, arg }, vnode) => {
if (!value) return
if (typeOf(value) != 'object') value = {}
vnode.componentInstance.print = Object.assign(value, { renderType: arg || 'input' })
}
}
Тогда напишите так на странице, вы можетеinsertedпри подключении к экземпляру компонентаdataначальство.
v-print:pick="{id:'orderBranchId',code:'orderBranchCode',name:'orderBranchName'}"
2. Создайте данные маршрутизации печати
Перед созданием данных нам нужно создать динамическую маршрутизацию и добавить внешний список маршрутизации:
{
path: '/print',
name: 'print',
component: Main,
children: [{
path: 'print-setting/:sheetType',
name: 'print-setting',
meta: {
title: '打印设置'
},
component: () => import('@/view/main-components/print-setting.vue')
}]
}
Чтобы сохранить данные постоянными, я сохраняю данные в хранилище и одновременно устанавливаю для них значение sessionStorage:
import { setSession } from '@/libs/session.js'
export default {
state: {
printTabs: {}
},
mutations: {
setPrintTab (state, tab) {
state.printTabs[tab.route] = tab.data
setSession(tab.route, tab.data)
}
}
}
После построения данных введите страницу печати:
this.setPrintTab({ route: this.$route.meta.code, data: params })
this.$router.push({ name: 'print-setting', params: { sheetType: this.$route.meta.code } })
2. Создайте шаблон печати
1. Интеграция и адаптация методом перетаскивания
Элемент перетаскивания печати состоит из четырех перетаскиваемых элементов, которые можно перетаскивать друг к другу, и здесь используется vuedraggable.
<Row style="height:100%">
<Form style="height:100%" justify :label-position="labelPositon" ref="formList">
<draggable id="formList" :list="formList" style="height:100%" group="people" :animation="150" :ghostClass="cls+'-left-item-chosen'">
<Col
:span="8*item.span"
:class="[cls+'-form-item',{'item-select':item.selected}]"
v-for="(item, index) in formList"
:key="index"
@click.native="handleFormItemClick(item, index)"
>
<form-item v-if="!item.blank" :label="item.label" >{{item.value}}</form-item>
<div :class="cls+'-blank'" v-else></div>
</Col>
</draggable>
</Form>
</Row>
Набор 4 перетаскиваемыхgroupОдинаковые можно перетаскивать друг к другу.
2, информация принтера
Прочитайте родной принтер:
PAZU.TPrinter.getPrinters()
Прочитайте текущую бумагу для принтера:
PAZU.TPrinter.getPaperForms()
Печать и проверка печати:
validatePrintExe () {
return new Promise((resolve, reject) => {
PAZU.TPrinter.getPrinters(res => {
if (res === 'err') {
resolve(false)
} else {
resolve(true)
}
})
})
},
async handlePrint () {
if (await this.validatePrintExe()) {
this.doPageSetup()
PAZU.print('printContent', null, null, true)
api.updatePrintCount({ ids: Object.values(this.printData.ids).join('~&z') }, this.printData.action)
} else {
this.showPrintDownLoad = true
}
}
Чтобы синхронизировать пользовательскую бумагу с принтером:
handleSynchronizeComfirm () {
this.$refs.synchronizeForm.validate(valid => {
if (valid) {
PAZU.TPrinter.createPaper(this.baseSetting.width, this.baseSetting.height, (res) => {
if (res) {
this.$Message.warning(`规格【${res}】的纸张已存在。`)
} else {
this.showPrintor = false
this.$Message.info('同步成功。')
}
}, this.synchronize.printName, this.synchronize.pageName)
}
})
}
Сводка проблем
Есть много проблем с печатью набора, и спрос огромен, но при написании главы документа я обнаружил, что не знаю, как в одностороннем порядке раскрыть портативные идеи и технические трудности. Я не знаю, как начать писать статью после этого.
1. Как сделать так, чтобы результаты веб-отображения и печати были согласованными?
- Web Display and Print Pattern использует один и тот же набор CSS и настраивается адаптивно.
2. Как распечатать картинки?
- Необходимо использовать тег img, а изображение можно преобразовать в base64.
3. Проблемы с печатью пустых страниц и как с ними бороться?
- Я строго слежу за веб-отображением, с точностью до 1px, чтобы в печати не было пустых страниц, и верстка была правильной, но когда количество печатаемых страниц превышает 100 страниц, он ограничивается браузером px для расчета десятичной дроби проблема с обработкой, и когда она достигает 100 страниц, возникает ошибка около 10 мм. Затем добавьте на каждой страницеpage-break-after: alwaysПотом будет необъяснимая пустая страница.
В-четвертых, динамическая маршрутизация Keep-alive
Подробности см. в статье «Изменение исходного кода vue для реализации поддержки активности ключа», которую я писал ранее)
Позже я подробно объясню, почему следует модифицировать исходный код и почему динамическая маршрутизация не работает. После официального выпуска vue3.0 я сначала протестирую 3.0keep-alive.