修改打印报告
This commit is contained in:
parent
9aa29fa6ab
commit
5ef0915ab8
721
public/templates/report-template.html
Normal file
721
public/templates/report-template.html
Normal file
@ -0,0 +1,721 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>体检检查报告</title>
|
||||
<!-- 添加PDF.js库 -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
|
||||
<style>
|
||||
.report-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.report-item {
|
||||
margin-bottom: 40px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.report-title {
|
||||
background-color: #4a90e2;
|
||||
color: white;
|
||||
padding: 15px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.report-content {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.report-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.report-content iframe {
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.report-summary {
|
||||
padding: 15px;
|
||||
background-color: #f9f9f9;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
/* 新增表格样式 */
|
||||
.exam-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.exam-table th, .exam-table td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.exam-table th {
|
||||
background-color: #f5f5f5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.exam-table tr:nth-child(even) {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* 默认隐藏打印占位符和打印专用内容 */
|
||||
.print-placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.print-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pdf-loading {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.pdf-error {
|
||||
color: red;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border: 1px solid #ffcccc;
|
||||
background-color: #fff8f8;
|
||||
}
|
||||
|
||||
.pdf-page-info {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.loading-spinner {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 3px solid #f3f3f3;
|
||||
border-top: 3px solid #3498db;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 10px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.pdf-image-container img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border: 1px solid #ddd;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
/* 打印专用样式 - 完全重写 */
|
||||
@media print {
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.report-container {
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
/* 一般检查特殊处理 */
|
||||
.general-exam {
|
||||
page-break-inside: avoid !important;
|
||||
break-inside: avoid !important;
|
||||
page-break-after: always !important;
|
||||
break-after: page !important;
|
||||
height: auto !important;
|
||||
min-height: auto !important;
|
||||
max-height: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
display: block !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* 一般检查的内容区域 */
|
||||
.general-exam .report-content {
|
||||
padding: 5px !important;
|
||||
margin: 0 !important;
|
||||
display: block !important;
|
||||
overflow: visible !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* 一般检查的表格 */
|
||||
.general-exam .exam-table {
|
||||
margin: 5px 0 !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
|
||||
.general-exam .exam-table th,
|
||||
.general-exam .exam-table td {
|
||||
padding: 2px !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
|
||||
/* 一般检查的小结 */
|
||||
.general-exam .report-summary {
|
||||
padding: 5px !important;
|
||||
margin: 0 !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
|
||||
.general-exam .report-summary h4 {
|
||||
margin: 2px 0 !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
|
||||
.general-exam .report-summary p {
|
||||
margin: 2px 0 !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
|
||||
/* 其他报告项目的样式 */
|
||||
.report-item:not(.general-exam) {
|
||||
page-break-after: always;
|
||||
break-after: page;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 最后一个报告不需要分页 */
|
||||
.report-item:last-child {
|
||||
page-break-after: auto;
|
||||
break-after: auto;
|
||||
}
|
||||
|
||||
/* 标题样式 */
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
padding: 8px 10px;
|
||||
font-size: 16px;
|
||||
background-color: #4a90e2 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.report-item:not(.general-exam) .report-content {
|
||||
padding: 10px;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
.report-item:not(.general-exam) .exam-table {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.report-item:not(.general-exam) .exam-table th,
|
||||
.report-item:not(.general-exam) .exam-table td {
|
||||
padding: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* 小结部分 */
|
||||
.report-item:not(.general-exam) .report-summary {
|
||||
padding: 8px;
|
||||
font-size: 11px;
|
||||
background-color: #f9f9f9 !important;
|
||||
}
|
||||
|
||||
.report-item:not(.general-exam) .report-summary h4 {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.report-item:not(.general-exam) .report-summary p {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
/* PDF图片容器 */
|
||||
.pdf-image-container {
|
||||
max-height: 500px;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pdf-image-container img {
|
||||
max-width: 100%;
|
||||
max-height: 480px;
|
||||
object-fit: contain;
|
||||
margin: 0 auto;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.pdf-page-info {
|
||||
font-size: 9px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
/* 隐藏屏幕元素 */
|
||||
.screen-only {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 显示打印元素 */
|
||||
.print-only {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* 确保背景色和边框在打印时可见 */
|
||||
.report-title,
|
||||
.exam-table th,
|
||||
.exam-table td,
|
||||
.report-summary {
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
}
|
||||
|
||||
/* 页面设置 */
|
||||
@page {
|
||||
margin: 0.5cm;
|
||||
size: A4 portrait;
|
||||
}
|
||||
|
||||
/* 超声检查报告的特殊样式 */
|
||||
.ultrasound-exam .pdf-image-container {
|
||||
max-height: 800px !important; /* 增加高度 */
|
||||
}
|
||||
|
||||
.ultrasound-exam .pdf-image-container img {
|
||||
max-width: 100% !important;
|
||||
max-height: 880px !important; /* 增加高度 */
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
/* 调整超声检查报告的内容区域 */
|
||||
.ultrasound-exam .report-content {
|
||||
padding: 5px !important;
|
||||
}
|
||||
|
||||
/* 调整超声检查报告的小结部分 */
|
||||
.ultrasound-exam .report-summary {
|
||||
padding: 5px !important;
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
.ultrasound-exam .report-summary p {
|
||||
margin: 3px 0 !important;
|
||||
font-size: 10px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="report-container">
|
||||
<h1>体检检查报告汇总</h1>
|
||||
|
||||
<!-- 一般检查部分 -->
|
||||
<div class="report-item general-exam">
|
||||
<div class="report-title">一般检查</div>
|
||||
<div class="report-content">
|
||||
<table class="exam-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>检查项目</th>
|
||||
<th>检查结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>体温</td>
|
||||
<td>36.5℃</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>脉率</td>
|
||||
<td>76次/分</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>呼吸频率</td>
|
||||
<td>18次/分</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>血压</td>
|
||||
<td>120/80 mmHg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>腰围</td>
|
||||
<td>82 cm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>身高</td>
|
||||
<td>170 cm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>体重</td>
|
||||
<td>65 kg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>体质指数(BMI)</td>
|
||||
<td>22.5 kg/m²</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<h4>体检科小结:</h4>
|
||||
<p>体格检查各项指标基本正常,BMI指数在正常范围内(18.5-24.9),血压控制良好。建议:保持良好的生活习惯,适量运动,合理膳食。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 超声检查报告 -->
|
||||
<div class="report-item ultrasound-exam">
|
||||
<div class="report-title">超声检查报告</div>
|
||||
<div class="report-content">
|
||||
<!-- 屏幕查看时显示PDF -->
|
||||
<div class="screen-only">
|
||||
<iframe src="https://pacs.gw12320.com/video/bc834b4d-f89c-4c51-bfe9-18f218c9d200/1741948447161.pdf#toolbar=0&navpanes=0&view=Fit"></iframe>
|
||||
</div>
|
||||
|
||||
<!-- 打印时显示渲染的PDF -->
|
||||
<div class="print-only pdf-container" data-pdf-url="https://pacs.gw12320.com/video/bc834b4d-f89c-4c51-bfe9-18f218c9d200/1741948447161.pdf">
|
||||
<div class="pdf-loading">正在准备PDF预览...</div>
|
||||
<!-- 添加图片容器,用于存放渲染后的图片 -->
|
||||
<div class="pdf-image-container" style="display:none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<p><strong>【所见】</strong>
|
||||
<br>1. 肝脏:大小正常,包膜光整,实质回声均匀,肝内管道结构清晰
|
||||
<br>2. 胆囊:大小正常,壁光滑,腔内无异常回声
|
||||
<br>3. 脾脏:位置正常,包膜完整,回声均匀
|
||||
<br>4. 胰腺:显示清晰,大小正常,回声均匀
|
||||
<br>5. 双肾:位置正常,大小对称,皮髓质分界清晰,集合系统未见分离
|
||||
</p>
|
||||
<p><strong>【所得】</strong>
|
||||
<br>1. 腹部超声未见明显异常
|
||||
<br>2. 建议定期复查</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 尿常规检查报告 -->
|
||||
<div class="report-item">
|
||||
<div class="report-title">尿常规检查报告</div>
|
||||
<div class="report-content">
|
||||
<!-- 屏幕查看时显示PDF -->
|
||||
<div class="screen-only">
|
||||
<iframe src="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946652424_20250314180412A007.pdf#toolbar=0&navpanes=0&view=Fit"></iframe>
|
||||
</div>
|
||||
|
||||
<!-- 打印时显示渲染的PDF -->
|
||||
<div class="print-only pdf-container" data-pdf-url="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946652424_20250314180412A007.pdf">
|
||||
<div class="pdf-loading">正在准备PDF预览...</div>
|
||||
<!-- 添加图片容器 -->
|
||||
<div class="pdf-image-container" style="display:none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<h4>检验科小结:</h4>
|
||||
<p>尿液常规检查各项指标在正常范围内,未见红细胞、白细胞异常,尿蛋白阴性,尿糖阴性,尿比重正常。提示:目前泌尿系统功能正常,请保持良好的饮水习惯,注意个人卫生。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 生化检查报告 -->
|
||||
<div class="report-item">
|
||||
<div class="report-title">生化检查报告</div>
|
||||
<div class="report-content">
|
||||
<!-- 屏幕查看时显示PDF -->
|
||||
<div class="screen-only">
|
||||
<iframe src="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946697780_20250314180457A010.pdf#toolbar=0&navpanes=0&view=Fit"></iframe>
|
||||
</div>
|
||||
|
||||
<!-- 打印时显示渲染的PDF -->
|
||||
<div class="print-only pdf-container" data-pdf-url="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946697780_20250314180457A010.pdf">
|
||||
<div class="pdf-loading">正在准备PDF预览...</div>
|
||||
<!-- 添加图片容器 -->
|
||||
<div class="pdf-image-container" style="display:none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<h4>检验科小结:</h4>
|
||||
<p>血糖、肝功能、肾功能各项指标均在正常范围内。血脂四项基本正常,总胆固醇略偏高。建议:
|
||||
<br>1. 注意饮食结构,控制高脂肪、高胆固醇食物的摄入
|
||||
<br>2. 规律运动,保持健康的生活方式
|
||||
<br>3. 建议半年后复查血脂</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 血常规检查报告 -->
|
||||
<div class="report-item">
|
||||
<div class="report-title">血常规检查报告</div>
|
||||
<div class="report-content">
|
||||
<!-- 屏幕查看时显示PDF -->
|
||||
<div class="screen-only">
|
||||
<iframe src="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946685652_20250314180445A009.pdf#toolbar=0&navpanes=0&view=Fit"></iframe>
|
||||
</div>
|
||||
|
||||
<!-- 打印时显示渲染的PDF -->
|
||||
<div class="print-only pdf-container" data-pdf-url="https://wlcblis.gw12320.com:8443/profile/upload/2025/03/14/1741946685652_20250314180445A009.pdf">
|
||||
<div class="pdf-loading">正在准备PDF预览...</div>
|
||||
<!-- 添加图片容器 -->
|
||||
<div class="pdf-image-container" style="display:none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<h4>检验科小结:</h4>
|
||||
<p>血红蛋白、白细胞、血小板计数均在正常范围内。各类白细胞比例正常,未见异常细胞。红细胞形态正常。提示:血液系统未见明显异常,建议继续保持良好的生活习惯,适当补充富含铁质的食物。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 心电图检查报告 -->
|
||||
<div class="report-item">
|
||||
<div class="report-title">心电图检查报告</div>
|
||||
<div class="report-content">
|
||||
<img src="https://zzxmc.gw12320.com/xdftp/0225030600184.jpg" alt="心电图检查">
|
||||
</div>
|
||||
<div class="report-summary">
|
||||
<p><strong>【所见】</strong>
|
||||
<br>1. 心率:75次/分
|
||||
<br>2. 心律:窦性心律
|
||||
<br>3. 电轴:正常心电轴
|
||||
<br>4. P波:形态正常,电位正常
|
||||
<br>5. PR间期:0.16秒
|
||||
<br>6. QRS波群:形态正常,时限正常
|
||||
<br>7. ST段:各导联未见异常改变
|
||||
<br>8. T波:形态正常,电位正常
|
||||
</p>
|
||||
<p><strong>【所得】</strong>
|
||||
<br>1. 正常心电图
|
||||
<br>2. 窦性心律</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加PDF渲染脚本 -->
|
||||
<script>
|
||||
// 设置PDF.js worker
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';
|
||||
|
||||
// 页面加载完成后立即开始预渲染所有PDF为图片
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('页面加载完成,开始预渲染PDF为图片');
|
||||
setTimeout(() => {
|
||||
preRenderAllPDFs();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// 预渲染所有PDF为图片
|
||||
async function preRenderAllPDFs() {
|
||||
const containers = document.querySelectorAll('.pdf-container');
|
||||
|
||||
for (const container of containers) {
|
||||
const pdfUrl = container.getAttribute('data-pdf-url');
|
||||
if (pdfUrl) {
|
||||
try {
|
||||
await renderPDFAsImage(pdfUrl, container);
|
||||
} catch (error) {
|
||||
console.error('预渲染PDF失败:', error);
|
||||
showPDFError(container, pdfUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('所有PDF预渲染完成');
|
||||
}
|
||||
|
||||
// 将PDF渲染为图片 - 完全重写
|
||||
async function renderPDFAsImage(url, container) {
|
||||
try {
|
||||
console.log('开始渲染PDF为图片:', url);
|
||||
const loadingElem = container.querySelector('.pdf-loading');
|
||||
const imageContainer = container.querySelector('.pdf-image-container');
|
||||
|
||||
// 加载PDF
|
||||
const loadingTask = pdfjsLib.getDocument({
|
||||
url: url,
|
||||
withCredentials: false,
|
||||
cMapUrl: 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/cmaps/',
|
||||
cMapPacked: true
|
||||
});
|
||||
|
||||
const pdf = await loadingTask.promise;
|
||||
console.log('PDF加载成功, 页数:', pdf.numPages);
|
||||
|
||||
// 只渲染第一页
|
||||
const page = await pdf.getPage(1);
|
||||
|
||||
// 检查是否为超声检查报告
|
||||
let scale = 1.5;
|
||||
// 查找最近的report-item父元素,检查是否有ultrasound-exam类
|
||||
const reportItem = container.closest('.report-item');
|
||||
if (reportItem && reportItem.classList.contains('ultrasound-exam')) {
|
||||
// 超声检查报告使用更大的缩放比例
|
||||
scale = 3.0;
|
||||
console.log('检测到超声检查报告,使用更大缩放比例:', scale);
|
||||
}
|
||||
|
||||
const viewport = page.getViewport({ scale: scale });
|
||||
|
||||
// 创建canvas
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
// 渲染PDF页面到canvas
|
||||
const renderContext = {
|
||||
canvasContext: context,
|
||||
viewport: viewport
|
||||
};
|
||||
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
// 裁剪canvas - 移除底部多余空白
|
||||
// 这里我们尝试自动检测内容区域,避免显示多余的空白
|
||||
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const data = imageData.data;
|
||||
|
||||
// 从底部向上扫描,找到最后一行非空白像素
|
||||
let bottomContentLine = canvas.height - 1;
|
||||
let foundContent = false;
|
||||
|
||||
// 向上扫描最多200像素,寻找内容
|
||||
for (let y = canvas.height - 1; y > canvas.height - 200 && !foundContent; y--) {
|
||||
for (let x = 0; x < canvas.width; x++) {
|
||||
const idx = (y * canvas.width + x) * 4;
|
||||
// 检查像素是否不是白色(简单判断)
|
||||
if (data[idx] < 240 || data[idx + 1] < 240 || data[idx + 2] < 240) {
|
||||
bottomContentLine = y + 20; // 添加一些边距
|
||||
foundContent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新的canvas,只包含内容部分
|
||||
const newCanvas = document.createElement('canvas');
|
||||
newCanvas.width = canvas.width;
|
||||
newCanvas.height = Math.min(bottomContentLine + 1, canvas.height);
|
||||
const newContext = newCanvas.getContext('2d');
|
||||
|
||||
// 将原canvas的内容复制到新canvas
|
||||
newContext.drawImage(
|
||||
canvas,
|
||||
0, 0, canvas.width, newCanvas.height,
|
||||
0, 0, newCanvas.width, newCanvas.height
|
||||
);
|
||||
|
||||
// 将新canvas转换为图片
|
||||
const imgData = newCanvas.toDataURL('image/png');
|
||||
const img = document.createElement('img');
|
||||
img.src = imgData;
|
||||
img.alt = 'PDF预览';
|
||||
|
||||
// 添加页码信息
|
||||
const pageInfo = document.createElement('p');
|
||||
// pageInfo.textContent = `第1页,共${pdf.numPages}页`;
|
||||
// pageInfo.className = 'pdf-page-info';
|
||||
|
||||
// 清空并添加图片
|
||||
imageContainer.innerHTML = '';
|
||||
imageContainer.appendChild(img);
|
||||
imageContainer.appendChild(pageInfo);
|
||||
|
||||
// 隐藏加载提示,显示图片
|
||||
if (loadingElem) loadingElem.style.display = 'none';
|
||||
imageContainer.style.display = 'block';
|
||||
|
||||
console.log('PDF渲染为图片完成');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('渲染PDF为图片失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示PDF错误信息
|
||||
function showPDFError(container, url) {
|
||||
const loadingElem = container.querySelector('.pdf-loading');
|
||||
if (loadingElem) loadingElem.style.display = 'none';
|
||||
|
||||
const imageContainer = container.querySelector('.pdf-image-container');
|
||||
imageContainer.innerHTML = `
|
||||
<div class="pdf-error">
|
||||
<p>无法加载PDF预览</p>
|
||||
<p>请访问以下链接查看完整报告:</p>
|
||||
<p>${url}</p>
|
||||
</div>
|
||||
`;
|
||||
imageContainer.style.display = 'block';
|
||||
}
|
||||
|
||||
// 打印前事件处理
|
||||
window.addEventListener('beforeprint', () => {
|
||||
console.log('打印前事件触发');
|
||||
// 显示所有打印容器
|
||||
document.querySelectorAll('.print-only').forEach(el => {
|
||||
el.style.display = 'block';
|
||||
});
|
||||
|
||||
// 检查是否所有PDF都已渲染为图片
|
||||
const containers = document.querySelectorAll('.pdf-container');
|
||||
let allRendered = true;
|
||||
|
||||
containers.forEach(container => {
|
||||
const imageContainer = container.querySelector('.pdf-image-container');
|
||||
if (imageContainer.style.display !== 'block') {
|
||||
allRendered = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!allRendered) {
|
||||
console.log('有PDF尚未渲染完成,尝试再次渲染');
|
||||
// 如果有未渲染完成的,尝试再次渲染
|
||||
preRenderAllPDFs().catch(error => {
|
||||
console.error('打印前渲染失败:', error);
|
||||
});
|
||||
} else {
|
||||
console.log('所有PDF已渲染为图片,可以直接打印');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -6,7 +6,7 @@
|
||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="flex items-center">
|
||||
<el-avatar :src="avatar" :size="70" class="mr-16px">
|
||||
<img src="@/assets/imgs/avatar.gif" alt="" />
|
||||
<!-- <img src="@/assets/imgs/avatar.gif" alt="" /> -->
|
||||
</el-avatar>
|
||||
<div>
|
||||
<div class="text-20px">
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<!-- <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="h-70px flex items-center justify-end lt-sm:mt-10px">
|
||||
<div class="px-8px text-right">
|
||||
<div class="mb-16px text-14px text-gray-400">{{ t('workplace.project') }}</div>
|
||||
@ -50,13 +50,13 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
</el-row>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-row class="mt-8px" :gutter="8" justify="space-between">
|
||||
<!-- <el-row class="mt-8px" :gutter="8" justify="space-between">
|
||||
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
@ -169,7 +169,7 @@
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row> -->
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { set } from 'lodash-es'
|
||||
|
165
src/views/summary/reprot-print/components/ReportPreview.vue
Normal file
165
src/views/summary/reprot-print/components/ReportPreview.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="体检报告预览"
|
||||
width="90%"
|
||||
top="3vh"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
class="report-preview-dialog"
|
||||
>
|
||||
<div class="iframe-container">
|
||||
<iframe
|
||||
v-if="dialogVisible"
|
||||
src="\templates\report-template.html"
|
||||
frameborder="0"
|
||||
style="width: 100%; height: 100%; border: none;"
|
||||
@load="handleIframeLoad"
|
||||
></iframe>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
<el-button type="primary" @click="handlePrint">
|
||||
打印报告
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
reportData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:visible', 'close'])
|
||||
|
||||
const dialogVisible = ref(props.visible)
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
dialogVisible.value = newVal
|
||||
if (newVal) {
|
||||
// 当对话框显示时,设置iframe内容
|
||||
setTimeout(() => {
|
||||
// setIframeContent()
|
||||
}, 100) // 给一点时间让DOM更新
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => dialogVisible.value,
|
||||
(newVal) => {
|
||||
emit('update:visible', newVal)
|
||||
}
|
||||
)
|
||||
|
||||
const handleIframeLoad = () => {
|
||||
const iframe = document.querySelector('iframe')
|
||||
if (iframe && iframe.contentWindow) {
|
||||
const doc = iframe.contentWindow.document
|
||||
if (props.reportData.pname) {
|
||||
const title = doc.querySelector('h1')
|
||||
if (title) {
|
||||
title.textContent = `体检报告 - ${props.reportData.pname}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handlePrint = () => {
|
||||
const iframe = document.querySelector('iframe')
|
||||
if (iframe && iframe.contentWindow) {
|
||||
// 在iframe内部创建一个加载提示
|
||||
const iframeDoc = iframe.contentWindow.document
|
||||
const loadingMessage = iframeDoc.createElement('div')
|
||||
loadingMessage.style.position = 'fixed'
|
||||
loadingMessage.style.top = '50%'
|
||||
loadingMessage.style.left = '50%'
|
||||
loadingMessage.style.transform = 'translate(-50%, -50%)'
|
||||
loadingMessage.style.padding = '20px'
|
||||
loadingMessage.style.background = 'rgba(0, 0, 0, 0.7)'
|
||||
loadingMessage.style.color = 'white'
|
||||
loadingMessage.style.borderRadius = '5px'
|
||||
loadingMessage.style.zIndex = '9999'
|
||||
loadingMessage.innerHTML = '正在准备打印,请稍候...'
|
||||
iframeDoc.body.appendChild(loadingMessage)
|
||||
|
||||
console.log('准备打印报告,等待2秒...')
|
||||
|
||||
// 延迟2秒后打印
|
||||
setTimeout(() => {
|
||||
// 移除加载提示
|
||||
iframeDoc.body.removeChild(loadingMessage)
|
||||
|
||||
// 执行打印
|
||||
iframe.contentWindow?.print()
|
||||
|
||||
// 打印完成后关闭窗口(如果是在新窗口中打开的)
|
||||
setTimeout(() => {
|
||||
if (window.opener) {
|
||||
window.close()
|
||||
}
|
||||
}, 1000)
|
||||
}, 4000)
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
emit('close')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog-footer {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.iframe-container {
|
||||
height: 80vh;
|
||||
overflow: hidden; /* 改为hidden,去掉滚动条 */
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0;
|
||||
overflow: hidden; /* 确保对话框内容区域也没有滚动条 */
|
||||
}
|
||||
|
||||
:deep(.el-dialog__header) {
|
||||
margin-right: 0;
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__footer) {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
:deep(.report-preview-dialog) {
|
||||
max-height: 94vh;
|
||||
margin: 3vh auto !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden; /* 确保整个对话框没有滚动条 */
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
flex: 1;
|
||||
overflow: hidden; /* 再次确保没有滚动条 */
|
||||
}
|
||||
</style>
|
@ -82,7 +82,7 @@
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 打印报告 -->
|
||||
<Dialog
|
||||
<!-- <Dialog
|
||||
v-model="printDialogVisible"
|
||||
width="84%"
|
||||
top="16px"
|
||||
@ -109,13 +109,23 @@
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Dialog> -->
|
||||
<!-- 使用报告预览组件 -->
|
||||
<ReportPreview
|
||||
v-model:visible="printDialogVisible"
|
||||
:report-data="currentReportData"
|
||||
@close="handlePreviewClose"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PatientApi, type PatientVO } from '@/api/inspect/inspectpatient'
|
||||
|
||||
// 使用相对路径导入组件
|
||||
import ReportPreview from './components/ReportPreview.vue'
|
||||
defineOptions({ name: 'ReportPrint' })
|
||||
//打印预览相关变量
|
||||
const printDialogVisible = ref(false)
|
||||
const currentReportData = ref({})
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
@ -163,26 +173,30 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
/** 打印报告按钮操作 */
|
||||
const printDialogVisible = ref(false)
|
||||
const printDialogLoading = ref(false)
|
||||
const printFileSrc = ref('')
|
||||
const handlePrint = async (row) => {
|
||||
try {
|
||||
printDialogVisible.value = true
|
||||
printDialogLoading.value = true
|
||||
const result = await PatientApi.createPatientInspectDataReport(row.medicalSn)
|
||||
if (result && result.code == '200') {
|
||||
printFileSrc.value = result.msg
|
||||
} else {
|
||||
throw '错误发生'
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('打印报告失败')
|
||||
} finally {
|
||||
if (printDialogLoading.value) printDialogLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
currentReportData.value = row
|
||||
printDialogVisible.value = true
|
||||
// try {
|
||||
// printDialogVisible.value = true
|
||||
// printDialogLoading.value = true
|
||||
// const result = await PatientApi.createPatientInspectDataReport(row.medicalSn)
|
||||
// if (result && result.code == '200') {
|
||||
// printFileSrc.value = result.msg
|
||||
// } else {
|
||||
// throw '错误发生'
|
||||
// }
|
||||
// } catch (error) {
|
||||
// message.error('打印报告失败')
|
||||
// } finally {
|
||||
// if (printDialogLoading.value) printDialogLoading.value = false
|
||||
// }
|
||||
}
|
||||
const handlePreviewClose = () => {
|
||||
currentReportData.value = {}
|
||||
}
|
||||
/** 日期格式化 */
|
||||
const dateFormatter = (row: any, column: any) => {
|
||||
if (!row.medicalDateTime) return ''
|
||||
|
Loading…
Reference in New Issue
Block a user