diff --git a/package.json b/package.json index 337fe81d..9fcb37fb 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "js-beautify": "1.13.0", "js-cookie": "3.0.1", "jsencrypt": "3.0.0-rc.1", + "jspdf": "^2.5.2", "jszip": "^3.10.1", "moment": "^2.30.1", "nprogress": "0.2.0", diff --git a/src/utils/bonus.js b/src/utils/bonus.js index de49f057..65d3883c 100644 --- a/src/utils/bonus.js +++ b/src/utils/bonus.js @@ -1,3 +1,5 @@ +import html2canvas from 'html2canvas' +import jsPDF from 'jspdf' /** * 通用js方法封装处理 * Copyright (c) 2019 bonus @@ -13,12 +15,15 @@ export function parseTime(time, pattern) { if (typeof time === 'object') { date = time } else { - if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { + if (typeof time === 'string' && /^[0-9]+$/.test(time)) { time = parseInt(time) } else if (typeof time === 'string') { - time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '') + time = time + .replace(new RegExp(/-/gm), '/') + .replace('T', ' ') + .replace(new RegExp(/\.[\d]{3}/gm), '') } - if ((typeof time === 'number') && (time.toString().length === 10)) { + if (typeof time === 'number' && time.toString().length === 10) { time = time * 1000 } date = new Date(time) @@ -30,7 +35,7 @@ export function parseTime(time, pattern) { h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), - a: date.getDay() + a: date.getDay(), } const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key] @@ -56,9 +61,10 @@ export function resetForm(refName) { // 添加日期范围 export function addDateRange(params, dateRange, propName) { let search = params - search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} + search.params = + typeof search.params === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} dateRange = Array.isArray(dateRange) ? dateRange : [] - if (typeof (propName) === 'undefined') { + if (typeof propName === 'undefined') { search.params['beginTime'] = dateRange[0] search.params['endTime'] = dateRange[1] } else { @@ -75,7 +81,7 @@ export function selectDictLabel(datas, value) { } var actions = [] Object.keys(datas).some((key) => { - if (datas[key].value == ('' + value)) { + if (datas[key].value == '' + value) { actions.push(datas[key].label) return true } @@ -100,7 +106,7 @@ export function selectDictLabels(datas, value, separator) { Object.keys(value.split(currentSeparator)).some((val) => { var match = false Object.keys(datas).some((key) => { - if (datas[key].value == ('' + temp[val])) { + if (datas[key].value == '' + temp[val]) { actions.push(datas[key].label + currentSeparator) match = true } @@ -114,8 +120,10 @@ export function selectDictLabels(datas, value, separator) { // 字符串格式化(%s ) export function sprintf(str) { - var args = arguments, flag = true, i = 1 - str = str.replace(/%s/g, function() { + var args = arguments, + flag = true, + i = 1 + str = str.replace(/%s/g, function () { var arg = args[i++] if (typeof arg === 'undefined') { flag = false @@ -161,7 +169,7 @@ export function handleTree(data, id, parentId, children) { let config = { id: id || 'id', parentId: parentId || 'parentId', - childrenList: children || 'children' + childrenList: children || 'children', } var childrenListMap = {} @@ -211,10 +219,10 @@ export function tansParams(params) { for (const propName of Object.keys(params)) { const value = params[propName] var part = encodeURIComponent(propName) + '=' - if (value !== null && value !== '' && typeof (value) !== 'undefined') { + if (value !== null && value !== '' && typeof value !== 'undefined') { if (typeof value === 'object') { for (const key of Object.keys(value)) { - if (value[key] !== null && value[key] !== '' && typeof (value[key]) !== 'undefined') { + if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') { let params = propName + '[' + key + ']' var subPart = encodeURIComponent(params) + '=' result += subPart + encodeURIComponent(value[key]) + '&' @@ -236,4 +244,74 @@ export function blobValidate(data) { // 处理表格索引延续问题 export function indexContinuation(num, size) { return (num - 1) * size + 1 -} \ No newline at end of file +} + +// 下载PDF +export async function downloadPDF(options) { + const { + id, // 要导出的 DOM id + fileName = '未命名', // 文件名 + modal, // this.$modal + message, // this.$message + margin = { top: 15, right: 15, bottom: 15, left: 15 }, + scale = 2, + } = options + + if (!id) { + console.error('downloadPDF: id is required') + return + } + + try { + modal?.loading?.('正在生成PDF,请稍候...') + + const element = document.getElementById(id) + if (!element) { + message?.error?.('未找到要导出的内容') + return + } + + const canvas = await html2canvas(element, { + scale, + useCORS: true, + allowTaint: true, + backgroundColor: '#ffffff', + }) + + const pdf = new jsPDF('p', 'mm', 'a4') + + const pageWidth = 210 + const pageHeight = 297 + + const contentWidth = pageWidth - margin.left - margin.right + const contentHeight = pageHeight - margin.top - margin.bottom + + const imgWidth = contentWidth + const imgHeight = (canvas.height * imgWidth) / canvas.width + + let heightLeft = imgHeight + let position = margin.top + + const imgData = canvas.toDataURL('image/jpeg', 1.0) + + // 首页 + pdf.addImage(imgData, 'JPEG', margin.left, position, imgWidth, imgHeight) + heightLeft -= contentHeight + + // 分页 + while (heightLeft > 0) { + pdf.addPage() + position = margin.top - (imgHeight - heightLeft) + pdf.addImage(imgData, 'JPEG', margin.left, position, imgWidth, imgHeight) + heightLeft -= contentHeight + } + + pdf.save(`${fileName}_${Date.now()}.pdf`) + message?.success?.('PDF下载成功') + } catch (error) { + console.error('生成PDF失败:', error) + message?.error?.('生成PDF失败,请稍后重试') + } finally { + modal?.closeLoading?.() + } +} diff --git a/src/views/EquipmentRoamRecord/maintenanceRecord/index.vue b/src/views/EquipmentRoamRecord/maintenanceRecord/index.vue index ccdb56ed..51e1c623 100644 --- a/src/views/EquipmentRoamRecord/maintenanceRecord/index.vue +++ b/src/views/EquipmentRoamRecord/maintenanceRecord/index.vue @@ -99,12 +99,13 @@ + 下载PDF 下载 打印 关闭 - +

维修记录单

@@ -167,6 +168,7 @@