Browse Source

打印:调整样式,添加pageConfig

lwx_v27
han2015 2 weeks ago
parent
commit
b8853c21e5
  1. 28
      src/components/DesignForm/tableListPage/index.vue
  2. 158
      src/components/DesignForm/tableListPage/printHtmlRender.vue
  3. 18
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js
  4. 64
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage2.vue

28
src/components/DesignForm/tableListPage/index.vue

@ -40,7 +40,7 @@ import { echatsViews } from "@/api/DesignForm/types";
import { formatNumber } from "@/api/DesignForm/utils"; import { formatNumber } from "@/api/DesignForm/utils";
import { Ref } from "vue"; import { Ref } from "vue";
import printHtmlRender from './printHtmlRender.vue' import printHtmlRender from './printHtmlRender.vue'
import {fieldTree} from './printHtmlRender.vue' import {fieldTree,pageConfig} from './printHtmlRender.vue'
import {printElement} from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js" import {printElement} from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js"
// //
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue"; import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
@ -1350,10 +1350,17 @@ const printRenderMode = ref(false);
const printRenderTree: Ref<any[]> = ref([]); const printRenderTree: Ref<any[]> = ref([]);
const printPage = async (row: any) => { const printPage = async (row: any) => {
let data:any[]=[] let data:any[]=[]
let pageWidth:string="210mm"
let title:string="表单"; let title:string="表单";
await getPrintTemplate({"versionid":props.versionid,"formkey":props.formKey}).then(resp=>{ await getPrintTemplate({"versionid":props.versionid,"formkey":props.formKey}).then(resp=>{
title=resp.data.title title=resp.data.title
data=JSON.parse(resp.data.formtemplatejson) if(resp.data.formtemplatejson!=""){
data=JSON.parse(resp.data.formtemplatejson)
}
if(resp.data.pageconfigjson!=""){
let pageConfig:pageConfig=JSON.parse(resp.data.pageconfigjson)
pageWidth=pageConfig.width
}
}) })
data.forEach(node=>{ data.forEach(node=>{
@ -1362,7 +1369,7 @@ const printPage = async (row: any) => {
printRenderTree.value=data printRenderTree.value=data
printRenderMode.value = true; printRenderMode.value = true;
ElMessageBox({ ElMessageBox({
message: () => h('div',{style:{ width:'1000px',display:'flex','flex-direction':'column'}},[ message: () => h('div',{style:{ width:'1200px',display:'flex','flex-direction':'column'}},[
h(ElButton, { h(ElButton, {
type:"primary", type:"primary",
style: "margin:10px 10px 5px auto;", style: "margin:10px 10px 5px auto;",
@ -1371,15 +1378,16 @@ const printPage = async (row: any) => {
} }
},'打印表单'), },'打印表单'),
h('div',{style:{ border: '1px solid black', width: 'fit-content', margin: '5px'}},[ h('div',{style:{ border: '1px solid black', width: 'fit-content', margin: '5px'}},[
h(printHtmlRender, { h(printHtmlRender,{
name:title, name:title,
fieldTree:printRenderTree.value, fieldTree:printRenderTree.value,
formData:row width:pageWidth,
}) formData:row
]) })
])
]), ]),
showConfirmButton:false, showConfirmButton:false,
customStyle: { '--el-messagebox-width':'1100px',padding:'10px'}, customStyle: { '--el-messagebox-width':'1300px',padding:'10px'},
}).then(() => { }).then(() => {
}) })

158
src/components/DesignForm/tableListPage/printHtmlRender.vue

@ -9,8 +9,17 @@ export interface fieldTree{
child?:fieldTree[] child?:fieldTree[]
} }
export interface pageConfig{
width:string,
height:string,
horizontal:string;//
pagesize:string;
}
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
name:string, name:string,
width:string,
fieldTree:fieldTree[], fieldTree:fieldTree[],
formData?:any formData?:any
}>(),{}) }>(),{})
@ -18,27 +27,19 @@ const props = withDefaults(defineProps<{
</script> </script>
<template style="width: 210mm;height: 297mm;"> <template>
<div id="printContainer" > <div id="printContainer" :style="{width:props.width}" >
<h3>{{props.name}}</h3> <h3>{{props.name}}</h3>
<div v-for="group in props.fieldTree"> <div v-for="group in props.fieldTree">
<div v-if="Array.isArray(group)"> <div v-if="Array.isArray(group)" style="display: grid; grid-template-columns: 1fr 1fr;">
<el-descriptions <template v-for="item in group" >
class="margin-top" <div v-if="item.checked!=2" class="cell_box">
:column="2" <span class="box_name">
border {{item.name}}
> </span>
<template v-for="item in group" > <span class="content">{{item.field}}</span>
<el-descriptions-item v-if="item.checked!=2"> </div>
<template #label>
<div class="cell-item">
{{item.name}}
</div>
</template>
{{item.field}}
</el-descriptions-item>
</template> </template>
</el-descriptions>
</div> </div>
<div v-else-if="group.type=='divider'" class="title" v-if="group.checked!=2">{{ group.name }}</div> <div v-else-if="group.type=='divider'" class="title" v-if="group.checked!=2">{{ group.name }}</div>
<div v-else-if="group.type=='textarea'" class="section" v-if="group.checked!=2"> <div v-else-if="group.type=='textarea'" class="section" v-if="group.checked!=2">
@ -47,32 +48,26 @@ const props = withDefaults(defineProps<{
</div> </div>
<div v-else-if="group.type=='table'" class="section_table" v-if="group.checked!=2"> <div v-else-if="group.type=='table'" class="section_table" v-if="group.checked!=2">
<h5>{{ group.name }}</h5> <h5>{{ group.name }}</h5>
<el-table class="table" :data="group.data" border style="width: 100%;margin:5px 10px 10px 10px"> <div class="bder_table" >
<template v-for="child in group.child"> <el-table class="table" :data="group.data" border >
<el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" /> <template v-for="child in group.child">
</template> <el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" />
</el-table> </template>
</el-table>
</div>
</div> </div>
<div v-else-if="group.type=='tabs'" class="section_tabs" v-if="group.checked!=2"> <div v-else-if="group.type=='tabs'" class="section_tabs" v-if="group.checked!=2">
<h5>{{ group.name }}</h5> <h5>{{ group.name }}</h5>
<div v-for="tabs in group.child" class="tabs_item"> <div v-for="tabs in group.child" class="tabs_item">
<div v-if="Array.isArray(tabs)"> <div v-if="Array.isArray(tabs)" style="display: grid; grid-template-columns: 1fr 1fr;">
<el-descriptions <template v-for="item in tabs" >
class="margin-top" <div v-if="item.checked!=2" class="tabs_cell_box" style="width: auto;">
:column="2" <span class="box_name">
border {{item.name}}++
> </span>
<template v-for="item in group" > <span class="content">{{item.field}}</span>
<el-descriptions-item v-if="item.checked!=2"> </div>
<template #label>
<div class="cell-item">
{{item.name}}
</div>
</template>
{{item.field}}
</el-descriptions-item>
</template> </template>
</el-descriptions>
</div> </div>
<div v-else-if="tabs.type=='divider'" class="title" v-if="tabs.checked!=2" <div v-else-if="tabs.type=='divider'" class="title" v-if="tabs.checked!=2"
style="font-size: 12px; margin-top: 20px;">{{ tabs.name }}</div> style="font-size: 12px; margin-top: 20px;">{{ tabs.name }}</div>
@ -82,13 +77,15 @@ const props = withDefaults(defineProps<{
</div> </div>
<div v-else-if="tabs.type=='table'" class="section" v-if="tabs.checked!=2"> <div v-else-if="tabs.type=='table'" class="section" v-if="tabs.checked!=2">
<h5>{{ tabs.name }}</h5> <h5>{{ tabs.name }}</h5>
<el-table class="table" border style="width: 100%;"> <div class="bder_table" >
<template v-for="child in tabs.child"> <el-table class="table" border >
<el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" /> <template v-for="child in tabs.child">
</template> <el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" />
</el-table> </template>
</el-table>
</div>
</div> </div>
<div v-else class="cell_box" v-if="tabs.checked!=2"> <div v-else class="tabs_cell_box" v-if="tabs.checked!=2">
<span class="box_name"> <span class="box_name">
{{tabs.name}} {{tabs.name}}
</span> </span>
@ -104,9 +101,9 @@ const props = withDefaults(defineProps<{
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
#printContainer{ #printContainer{
width: 210mm; // width: 210mm;
height: 297mm; // height: 297mm;
padding: 30px 0px 15px 0px; padding: 57px;
text-align: center; text-align: center;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -147,25 +144,20 @@ h5{
.section_title{ .section_title{
width:100% width:100%
} }
.section_table{
width: 96%;
}
.normal_cell,.normal_cell_field{ .normal_cell,.normal_cell_field{
width: 23%; width: 23%;
height: 20px; height: 20px;
background-color: #f5f7fa;
}
.normal_cell_field{
background-color: white;
} }
.section{ .section{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.section_tabs{ .section_tabs{
margin: 10px; margin: 10px 0;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
@ -174,14 +166,14 @@ h5{
border: 1px solid rgb(182, 181, 181); border: 1px solid rgb(182, 181, 181);
border-radius: 3px; border-radius: 3px;
min-height: 40px; min-height: 40px;
margin: 5px 10px 10px 10px; margin: 5px 0px 10px 0px;
} }
////////////// //////////////
.tabs_item { .tabs_item {
display: inline-flex; display: inline-flex;
min-height: 40px; min-height: 40px;
min-width: 50%; /* 默认最小宽度 */ min-width: 50%; /* 默认最小宽度 */
margin-right: -1px;/* 解决边框重合问题*/
/* 默认情况:没有 title/section 时宽度 50% */ /* 默认情况:没有 title/section 时宽度 50% */
width: 50%; width: 50%;
.section{ .section{
@ -195,29 +187,39 @@ h5{
width: 100%; width: 100%;
} }
.bder_table{
border: 1px solid rgb(182, 181, 181);
margin:5px 0px 10px 0px;
width: 100% !important; /* 确保表格不超出父容器 */
overflow-x: hidden;
}
/* 原有样式(稍作优化) */ /* 原有样式(稍作优化) */
.cell_box { .cell_box, .tabs_cell_box {
width: 100%; border: 1px solid rgb(182, 181, 181);
border: 1px solid #ebeef5; margin-right: -1px; /* 水平排列时用右负margin */
margin-bottom: -1px; /* 垂直排列时用下负margin */
display: inline-flex; display: inline-flex;
.box_name { .box_name {
background-color: #f5f7fa; padding: 8px 2px;
padding: 8px 11px;
width: 50%; width: 50%;
text-wrap: wrap; text-wrap: wrap;
text-overflow: ellipsis;
max-height: 80px; max-height: 80px;
overflow: hidden; /* 配合 ellipsis 需要 */ overflow: hidden; /* 配合 ellipsis 需要 */
border-right: 1px solid rgb(182, 181, 181);
} }
.content { .content {
padding: 8px 11px; padding: 8px 2px;
width: 50%; width: 50%;
text-wrap: wrap; text-wrap: wrap;
word-break: break-all; word-break: break-all;
} }
} }
.tabs_cell_box{
width: 100%;
}
</style> </style>
<style> <style>
@ -226,15 +228,23 @@ h5{
border: 0px solid; border: 0px solid;
border-spacing: 1px; border-spacing: 1px;
border-collapse: collapse; border-collapse: collapse;
th{ }
background-color: #e5e5e5; #printContainer .el-table th.el-table__cell{
border: 1px solid; background: none !important;
min-width: 180px; word-wrap: break-word;
}
#printContainer .el-table .cell{
padding: 0 5px;
text-align: center;
}
#printContainer table th{
font-weight: normal;
border-right: 1px solid rgb(182, 181, 181);
} }
td{ #printContainer table td{
border: 1px solid; border: 1px solid rgb(182, 181, 181);
min-width: 180px;
} }
}
</style> </style>

18
src/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js

@ -27,6 +27,24 @@ export function printElement(elementId) {
@media print { @media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; } body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
} }
#printContainer table{
display: block;
border: 0px solid;
border-spacing: 1px;
border-collapse: collapse;
}
#printContainer .el-table th.el-table__cell{
background: none !important;
}
#printContainer table th{
border-right: 1px solid;
}
#printContainer table td{
border: 1px solid;
}
/* 复制原页面样式 */ /* 复制原页面样式 */
${Array.from(document.styleSheets) ${Array.from(document.styleSheets)
.map(sheet => { .map(sheet => {

64
src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage2.vue

@ -7,7 +7,7 @@
import { ref, onMounted,toRaw} from 'vue'; import { ref, onMounted,toRaw} from 'vue';
import {getPrintTemplate,savePrintTemplate} from '@/api/DesignForm/requestapi' import {getPrintTemplate,savePrintTemplate} from '@/api/DesignForm/requestapi'
import printHtmlRender from '@/components/DesignForm/tableListPage/printHtmlRender.vue' import printHtmlRender from '@/components/DesignForm/tableListPage/printHtmlRender.vue'
import {fieldTree} from '@/components/DesignForm/tableListPage/printHtmlRender.vue' import {fieldTree,pageConfig} from '@/components/DesignForm/tableListPage/printHtmlRender.vue'
import { fieldList } from '@/views/sysworkflow/codepage/mathFunction'; import { fieldList } from '@/views/sysworkflow/codepage/mathFunction';
import { extend } from 'dayjs'; import { extend } from 'dayjs';
@ -24,6 +24,10 @@ const htmlRenderData=ref<any[]>([])
let defaultCheckList:string[]=[] let defaultCheckList:string[]=[]
const treeLoaded=ref(false) // const treeLoaded=ref(false) //
const fieldTreeRef=ref() const fieldTreeRef=ref()
const pageConfig=ref<pageConfig>({width:'210mm',height:'297mm',horizontal:"vtal",pagesize:"A4"})
const pageSize=ref('A4')
const pageDret=ref('vtal')
const props = defineProps({ const props = defineProps({
appCont: { appCont: {
@ -66,6 +70,39 @@ function safeStringify(obj, space = 2) {
return toRaw(value) ?? value; // ProxytoRaw undefined ?? return toRaw(value) ?? value; // ProxytoRaw undefined ??
}, space); }, space);
} }
function updatePageConfig(cmd:string){
switch(cmd){
case "A4":
pageConfig.value.pagesize="A4"
pageConfig.value.width="210mm"
pageConfig.value.height="297mm"
break
case "A5":
pageConfig.value.pagesize="A5"
pageConfig.value.width="148mm"
pageConfig.value.height="210mm"
break
case "htal":
pageConfig.value.horizontal="htal"
break
default:
pageConfig.value.horizontal="vtal"
}
if(pageConfig.value.horizontal=="htal"){
if(pageConfig.value.width<pageConfig.value.height){
let a=pageConfig.value.width
pageConfig.value.width=pageConfig.value.height
pageConfig.value.height=a
}
}else if(pageConfig.value.width>pageConfig.value.height){
let a=pageConfig.value.width
pageConfig.value.width=pageConfig.value.height
pageConfig.value.height=a
}
}
// //
function onSaveTreeData(){ function onSaveTreeData(){
let str:string=safeStringify(htmlRenderData.value) let str:string=safeStringify(htmlRenderData.value)
@ -77,6 +114,7 @@ function onSaveTreeData(){
formkey:props.formKey, formkey:props.formKey,
formtemplatejson:str, formtemplatejson:str,
treedatajson:strtree, treedatajson:strtree,
pageconfigjson:JSON.stringify(pageConfig.value),
nodecheckedlist:JSON.stringify(fieldTreeRef.value.getCheckedKeys()) // nodecheckedlist:JSON.stringify(fieldTreeRef.value.getCheckedKeys()) //
}).then(resp=>{ }).then(resp=>{
if (resp.code!=200){ if (resp.code!=200){
@ -214,8 +252,15 @@ onMounted(async ()=>{
printMode.value=resp.data.type printMode.value=resp.data.type
if(resp.data.formtemplatejson!=""){ if(resp.data.formtemplatejson!=""){
fieldTreeData.value = JSON.parse(resp.data.treedatajson) fieldTreeData.value = JSON.parse(resp.data.treedatajson)
}
if(resp.data.nodecheckedlist!=""){
defaultCheckList=JSON.parse(resp.data.nodecheckedlist) defaultCheckList=JSON.parse(resp.data.nodecheckedlist)
} }
if(resp.data.pageconfigjson!=""){
pageConfig.value=JSON.parse(resp.data.pageconfigjson)
pageDret.value=pageConfig.value.horizontal??"vtal"
pageSize.value=pageConfig.value.pagesize??"A4"
}
}).catch((err)=>{ }).catch((err)=>{
ElMessage({ ElMessage({
message: "模板加载失败,使用默认模板"+err, message: "模板加载失败,使用默认模板"+err,
@ -276,8 +321,21 @@ function updateNodeData(val:fieldTree,val2:boolean,val3:boolean){
</template> </template>
</el-tree> </el-tree>
</div> </div>
<div style="border: 1px solid black; width: fit-content; margin: 5px;"> <div style="border: 1px solid black;margin: 5px;">
<printHtmlRender :name="props.state.formOtherData.formName" :field-tree="htmlRenderData" /> <div style="display: flex;justify-content:center">
<el-radio-group v-model="pageSize" fill="#6cf" @change="(val)=>updatePageConfig(val)">
<el-radio-button label="A4" value="A4" />
<el-radio-button label="A5" value="A5" />
</el-radio-group>
<el-radio-group v-model="pageDret" fill="#6cf" @change="(val)=>updatePageConfig(val)">
<el-radio-button label="横向" value="htal" />
<el-radio-button label="纵向" value="vtal" />
</el-radio-group>
</div>
<div style="margin: 5px; border: 1px dashed black;overflow-y: scroll; scrollbar-width: none;" :style="{width: pageConfig.width,height:pageConfig.height}">
<printHtmlRender :name="props.state.formOtherData.formName" :width="pageConfig.width" :field-tree="htmlRenderData" />
</div>
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>

Loading…
Cancel
Save