vue3+ts 前端实现打印功能

1.安装插件
npm install vue3-print-nb --save
2.全局引用
import { createApp } from ‘vue’
import App from ‘./App.vue’
import print from ‘vue3-print-nb’
const app = createApp(App)
app.use(print)
app.mount(‘#app’)
例子

<template>
	<div>
		<el-dialog v-model="jfDialogVisible" title="机房出入详情" width="60%" @close="close">
			<div id="a">
				<img class="pass" v-if="params.applyStatus == '2'" src="../../../assets/images/pass.png" />
				<div class="title">申请信息:</div>
				<table>
					<tr>
						<th width="80px">申请单号:</th>
						<td>{{ params.applyNumber }}</td>
						<th>状态:</th>
						<td>{{ applyStatusEnum[params.applyStatus] }}</td>
					</tr>
					<tr>
						<th width="80px">申请时间:</th>
						<td>{{ params.applyTime }}</td>
						<th>缓急:</th>
						<td>{{ urgentFlagData[params.urgentFlag] }}</td>
					</tr>
					<tr>
						<th>申请人:</th>
						<td>{{ params.applyUserName }}</td>
						<th width="80px">联系电话:</th>
						<td>{{ params.mobilePhone }}</td>
					</tr>
					<tr>
						<th width="120px">所属单位团队:</th>
						<td colspan="3">{{ params.unitTeam }}</td>
					</tr>
					<tr>
						<th width="80px">机房名称:</th>
						<td colspan="3">{{ params.roomName }}</td>
					</tr>
					<tr>
						<th width="80px">机房地址:</th>
						<td colspan="3">{{ params.roomAddress }}</td>
					</tr>
					<tr>
						<th>申请出入时间:</th>
						<td colspan="3">{{ params.accessBegin }}至{{ params.accessEnd }}</td>
					</tr>
					<tr>
						<th width="80px">工作内容:</th>
						<td colspan="3">{{ params.jobContent }}</td>
					</tr>
					<tr>
						<th width="80px">携带物资:</th>
						<td colspan="3">{{ params.bring }}</td>
					</tr>
				</table>
				<div class="title">通行人员名单:</div>
				<table>
					<tr>
						<th width="50px">序号</th>
						<th width="50px">姓名</th>
						<th width="50px">性别</th>
						<th width="150px">单位</th>
						<th width="150px">身份证号码</th>
						<th>备注</th>
					</tr>
					<tr v-for="(item, index) in passList" :key="index">
						<td>{{ index + 1 }}</td>
						<td>{{ item.name }}</td>
						<td>{{ genderData[item.gender] }}</td>
						<td>{{ item.unit }}</td>
						<td>{{ item.sfz }}</td>
						<td>{{ item.remark }}</td>
					</tr>
					<tr class="no-data-row" v-if="passList.length == 0">
						<td colspan="6">暂无数据</td>
					</tr>
				</table>
				<div class="title">机房通行信息:</div>
				<table>
					<tr>
						<th width="120px">同意出入时间:</th>
						<td>{{ params.passtimeBegin }}至{{ params.passtimeEnd }}</td>
						<th>机房联系电话:</th>
						<td>{{ params.roomPhone }}</td>
					</tr>
					<tr>
						<th width="80px">陪同人员:</th>
						<td>{{ params.escortUser }}</td>
						<th width="120px">陪同人员电话:</th>
						<td>{{ params.escortPhone }}</td>
					</tr>
					<tr>
						<th width="80px">其他安排:</th>
						<td colspan="3">{{ params.remark }}</td>
					</tr>
				</table>
				<div class="title">申请/审核过程:</div>
				<table>
					<tr>
						<th width="100px">流程节点</th>
						<th width="80px">经办人</th>
						<th width="80px">办理结果</th>
						<th>建议/意见</th>
						<th width="180px">办理时间</th>
					</tr>
					<tr v-for="(item, index) in hdxqData" :key="index">
						<td>{{ item.jdm }}</td>
						<td>{{ item.jbr }}</td>
						<td>{{ item.bljg }}</td>
						<td>{{ item.shyj }}</td>
						<td>{{ item.qssj }}</td>
					</tr>
					<tr class="no-data-row" v-if="hdxqData.length == 0">
						<td colspan="5">暂无数据</td>
					</tr>
				</table>
			</div>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="jfDialogVisible = false">取消</el-button>
					<el-button type="primary" v-print="printObj">打印 </el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import { getRoomApplyByApplyId } from "@/api/modules/roomApplyApi/applyApi";
import { queryDictEnum, queryDictData } from "@/api/modules/system/dictApi";
import { loadHdxqList } from "@/api/modules/workflow/jylcApi";
import { dayjs } from "element-plus";
const jfDialogVisible = ref(false);
const passList = ref<any>([]);
const hdxqData = ref<any>([]);
interface Props {
	ywbh?: any;
}
//打印的属性设置
const printObj = ref({
	id: "a", // 这里是要打印元素的ID
	popTitle: "&nbsp;", // 打印的标题
	extraCss: "", // 打印可引入外部的一个 css 文件
	extraHead: `
        <style>
          .extra-head-text {
            text-align: center;
			font-weight: bold;
			font-size: 20px;
          }
        </style>
        <div class="extra-head-text">
          机房出入申请单明细
        </div>
      ` // 打印头部文字
});

const props = defineProps<Props>();
const emit = defineEmits(["hide"]);
const close = () => {
	emit("hide");
	jfDialogVisible.value = false;
};
const params = ref();
//获取打印信息
const jfDialog = (val: any) => {
	getRoomApplyByApplyId(val).then((res: any) => {
		params.value = res.data;
		params.value.accessBegin = dayjs(params.value.accessBegin).format("YYYY年MM月DD日");
		params.value.accessEnd = dayjs(params.value.accessEnd).format("YYYY年MM月DD日");
		params.value.passtimeBegin = dayjs(params.value.passtimeBegin).format("YYYY年MM月DD日");
		params.value.passtimeEnd = dayjs(params.value.passtimeEnd).format("YYYY年MM月DD日");
		passList.value = res.data.passersList;
	});
	jfDialogVisible.value = true;
	loadHdxqData();
};
//获取审核信息列表
const loadHdxqData = async () => {
	const res = await loadHdxqList(props.ywbh);
	if (res.code === 200) {
		hdxqData.value = res.data as any;
	}
};

const applyStatusEnum = ref<any>({});
//获取通知公告状态
const getApplyStatus = () => {
	queryDictEnum("RoomApplyStatusEnum_wos-workorder").then((res: any) => {
		res.data.forEach((item: any) => {
			applyStatusEnum.value[item.value] = item.label;
		});
	});
};
const urgentFlagData = ref<any>({});
const genderData = ref<any>({});
//获取缓急程度
const getUrgentFlag = () => {
	queryDictData("URGENT").then((res: any) => {
		res.data.forEach((item: any) => {
			urgentFlagData.value[item.value] = item.label;
		});
	});
};
//获取性别
const getGender = () => {
	queryDictData("COMMON_GENDER").then((res: any) => {
		res.data.forEach((item: any) => {
			genderData.value[item.value] = item.label;
		});
	});
};
getGender();
getUrgentFlag();
getApplyStatus();
defineExpose({
	jfDialog
});
</script>
<style scoped lang="scss">
.title {
	margin: 10px 0;
	font-weight: bold;
	font-size: 15px;
}
.no-data-row td {
	text-align: center;
	font-weight: bold;
	color: gray;
	height: 200px;
}
table {
	border-collapse: collapse;
	width: 100%;
}

table,
th,
td {
	border: 1px solid gray;
}
#a {
	position: relative;
}
.pass {
	position: absolute;
	top: 25px;
	right: 0px;
	opacity: 0.4;
}
th,
td {
	padding: 8px;
	text-align: left;
}
</style>

可以使用 `pdfjs-dist` 库来解析 PDF 文件,然后使用 `FileSaver` 库将生成的 PDF 文件保存到本地。以下是一个使用 TypeScript 和 Vue 3 的示例代码: ```typescript <template> <div class="container"> <input type="file" @change="onFileChange"> <button @click="generatePdf">Generate PDF</button> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { PDFDocument } from 'pdf-lib'; import { saveAs } from 'file-saver'; export default defineComponent({ name: 'PdfGenerator', data() { return { file: null as File | null, pdfDoc: null as PDFDocument | null, }; }, methods: { async onFileChange(event: Event) { const file = (event.target as HTMLInputElement).files?.[0]; if (!file) return; const base64Data = await this.readAsBase64(file); this.pdfDoc = await PDFDocument.load(base64Data); }, async generatePdf() { if (!this.pdfDoc) return; const pdfBytes = await this.pdfDoc.save(); const blob = new Blob([pdfBytes], { type: 'application/pdf' }); saveAs(blob, 'generated.pdf'); }, readAsBase64(file: File): Promise<string> { return new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { resolve(reader.result as string); }; }); }, }, }); </script> ``` 在这个示例中,我们通过 `input` 元素选择一个 PDF 文件,并将其转换为基于 Base64 的数据。然后,我们使用 `pdf-lib` 库加载 PDF 文档,并在用户单击“Generate PDF”按钮时将其保存到本地。我们使用 `file-saver` 库来保存生成的 PDF 文件。 请注意,这只是一个基本示例,并且需要根据您的具体需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值