<!doctype html>
|
<html>
|
<head>
|
<meta charset="UTF-8" />
|
<style>
|
* {
|
margin: 0;
|
padding: 0;
|
box-sizing: border-box;
|
}
|
|
body {
|
font-family: 'SimSun', 'Microsoft YaHei', sans-serif;
|
font-size: 3mm;
|
line-height: 1.35;
|
color: #000;
|
}
|
|
table {
|
width: 100%;
|
border-collapse: collapse;
|
table-layout: fixed;
|
}
|
|
td,
|
th {
|
border: 1px solid #333;
|
padding: 1mm 1.2mm;
|
text-align: center;
|
vertical-align: middle;
|
word-break: break-all;
|
}
|
|
.page {
|
width: 210mm;
|
min-height: 297mm;
|
background: #fff;
|
padding: 10mm;
|
}
|
|
.header-table {
|
margin-bottom: 2mm;
|
}
|
|
.logo-cell {
|
height: 22mm;
|
padding: 0.5mm;
|
}
|
|
.logo-placeholder {
|
width: 20mm;
|
height: 20mm;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin: 0 auto;
|
}
|
|
.logo-placeholder img {
|
width: 100%;
|
height: 100%;
|
object-fit: contain;
|
}
|
|
.company-name {
|
font-size: 5mm;
|
font-weight: bold;
|
letter-spacing: 0;
|
}
|
|
.report-name {
|
font-size: 3.6mm;
|
font-weight: bold;
|
}
|
|
.doc-number {
|
font-size: 3.6mm;
|
font-weight: bold;
|
}
|
|
.label-cell {
|
font-weight: bold;
|
background: #fafafa;
|
}
|
|
.checkbox-line {
|
display: inline-flex;
|
gap: 4mm;
|
align-items: center;
|
}
|
|
.check {
|
font-family: 'SimSun', serif;
|
white-space: nowrap;
|
}
|
|
.main-table td {
|
height: 7.2mm;
|
}
|
|
.sample-header td {
|
font-weight: bold;
|
height: 8mm;
|
}
|
|
.sample-row td {
|
height: 7.2mm;
|
}
|
|
.standard-table td {
|
height: 7mm;
|
}
|
|
.signature-row td {
|
height: 9mm;
|
}
|
|
.left {
|
text-align: left;
|
}
|
|
@media screen {
|
body {
|
background: #f0f0f0;
|
padding: 10mm;
|
}
|
|
.page {
|
margin: 0 auto 10mm;
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.12);
|
}
|
}
|
|
@media print {
|
@page {
|
size: A4;
|
margin: 0;
|
}
|
|
body {
|
background: #fff;
|
padding: 0;
|
}
|
|
.page {
|
min-height: 297mm;
|
height: 297mm;
|
break-after: page;
|
page-break-after: always;
|
box-shadow: none;
|
overflow: hidden;
|
}
|
|
.page:last-child {
|
break-after: auto;
|
page-break-after: auto;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
<div id="print-container"></div>
|
|
<script>
|
const templateData = window.templateData || {};
|
const header = templateData.header || {};
|
const items = templateData.items || [];
|
const standardRows = templateData.standardRows || templateData.standard_rows || [];
|
const signatures = templateData.signatures || {};
|
const PAGE_SIZE = 26;
|
|
function escapeHtml(text) {
|
if (text === null || text === undefined) return '';
|
return String(text)
|
.replace(/&/g, '&')
|
.replace(/</g, '<')
|
.replace(/>/g, '>')
|
.replace(/"/g, '"')
|
.replace(/'/g, ''');
|
}
|
|
function value() {
|
for (let i = 0; i < arguments.length; i++) {
|
const v = arguments[i];
|
if (v !== null && v !== undefined && v !== '') return v;
|
}
|
return '';
|
}
|
|
function reportText(text) {
|
return String(text || '').replace(/洁净区表面微生物/g, '表面微生物');
|
}
|
|
function checked(condition) {
|
return condition ? '☑' : '□';
|
}
|
|
function isStaticStatus() {
|
return ['jingtai', 'static', '静态'].includes(String(header.jiance_zhuangtai || '').toLowerCase());
|
}
|
|
function isDynamicStatus() {
|
return ['dongtai', 'dynamic', '动态'].includes(String(header.jiance_zhuangtai || '').toLowerCase());
|
}
|
|
function isYes(v) {
|
return ['yes', 'true', '1', '是', '合格', 'compliant', 'qualified', '符合规定', 'fuheguiding'].includes(String(v || '').toLowerCase());
|
}
|
|
function isNo(v) {
|
return ['no', 'false', '0', '否', '不合格', 'non_compliant', 'uncompliant', 'unqualified', '不符合规定', 'bufuheguiding'].includes(String(v || '').toLowerCase());
|
}
|
|
function signatureText(sig) {
|
if (!sig) return '';
|
return [sig.name || '', sig.date || ''].filter(Boolean).join(' / ');
|
}
|
|
function sampleCell(item, resultColspan, passColspan) {
|
const resultAttr = resultColspan > 1 ? ' colspan="' + resultColspan + '"' : '';
|
const passAttr = passColspan > 1 ? ' colspan="' + passColspan + '"' : '';
|
if (!item) {
|
return '<td></td><td' + resultAttr + '></td><td' + passAttr + '></td>';
|
}
|
const pointName = value(item.quyangdian_mingcheng, item.weizhi_mingcheng, item.weizhi_bianhao);
|
return (
|
'<td>' +
|
escapeHtml(pointName) +
|
'</td><td' +
|
resultAttr +
|
'>' +
|
escapeHtml(item.ceshi_jieguo) +
|
'</td><td' +
|
passAttr +
|
'><span class="check">' +
|
checked(isYes(item.shifou_hege)) +
|
'是 ' +
|
checked(isNo(item.shifou_hege)) +
|
'否</span></td>'
|
);
|
}
|
|
function generateHeaderHTML(pageNum, totalPages) {
|
return (
|
'<table class="header-table">' +
|
'<colgroup><col style="width: 16%" /><col style="width: 52%" /><col style="width: 15%" /><col style="width: 17%" /></colgroup>' +
|
'<tr><td class="logo-cell"><div class="logo-placeholder"><img src="/logo.png" alt="Logo"></div></td><td colspan="3" class="company-name">' +
|
escapeHtml(templateData.companyName || '') +
|
'</td></tr>' +
|
'<tr><td class="label-cell">记录名称</td><td class="report-name">' +
|
escapeHtml(reportText(templateData.template_name || '表面微生物检测记录')) +
|
'</td><td class="label-cell">页码</td><td>' +
|
pageNum +
|
' / ' +
|
totalPages +
|
'</td></tr>' +
|
'<tr><td class="label-cell">记录编号</td><td class="doc-number">' +
|
escapeHtml(templateData.docNumber || '') +
|
'</td><td class="label-cell">回顾周期</td><td>' +
|
escapeHtml(templateData.reviewCycle || '') +
|
'</td></tr>' +
|
'<tr><td class="label-cell">分发部门</td><td>' +
|
escapeHtml(templateData.distributionDepartment || '') +
|
'</td><td class="label-cell">生效日期</td><td>' +
|
escapeHtml(templateData.effectiveDate || '') +
|
'</td></tr>' +
|
'</table>'
|
);
|
}
|
|
function generateInfoRowsHTML() {
|
return (
|
'<tr><td colspan="2" class="label-cell">检测区域</td><td colspan="5">' +
|
escapeHtml(header.jiance_quyu_name || header.jiance_quyu) +
|
'</td><td class="label-cell">检测日期</td><td colspan="3">' +
|
escapeHtml(header.jiance_riqi) +
|
'</td></tr>' +
|
'<tr><td colspan="2" class="label-cell">培养基批号</td><td colspan="5">' +
|
escapeHtml(header.peiyangji_pihao) +
|
'</td><td class="label-cell">培养基有效期</td><td colspan="3">' +
|
escapeHtml(header.peiyangji_youxiaoqi) +
|
'</td></tr>' +
|
'<tr><td colspan="2" class="label-cell">培养设备编号</td><td colspan="5">' +
|
escapeHtml(header.peiyang_shebei_biaohao) +
|
'</td><td class="label-cell">校准有效期</td><td colspan="3">' +
|
escapeHtml(header.jiaozhun_youxiaoqi) +
|
'</td></tr>' +
|
'<tr><td colspan="2" class="label-cell">培养开始时间</td><td colspan="5">' +
|
escapeHtml(header.peiyang_kaishi_shijian) +
|
'</td><td class="label-cell">结束时间</td><td colspan="3">' +
|
escapeHtml(header.peiyang_jieshu_shijian) +
|
'</td></tr>' +
|
'<tr><td colspan="2" class="label-cell">检测方法</td><td colspan="9">' +
|
escapeHtml(reportText(templateData.methodText || '')) +
|
'</td></tr>'
|
);
|
}
|
|
function generateSampleRowsHTML(chunk) {
|
let html =
|
'<tr class="sample-header"><td>取样点</td><td colspan="3">测试结果</td><td colspan="3">是否符合规定</td><td>取样点</td><td colspan="2">测试结果</td><td>是否符合规定</td></tr>';
|
for (let i = 0; i < chunk.length; i += 2) {
|
const left = chunk[i];
|
const right = chunk[i + 1];
|
html += '<tr class="sample-row">' + sampleCell(left, 3, 3) + sampleCell(right, 2, 1) + '</tr>';
|
}
|
return html;
|
}
|
|
function generateStandardRowsHTML() {
|
const rows = standardRows.length
|
? standardRows
|
: [
|
{ level: 'A', static_limit: '<1', dynamic_limit: '<1' },
|
{ level: 'C', static_limit: '25', dynamic_limit: '25' },
|
{ level: 'D', static_limit: '50', dynamic_limit: '50' },
|
];
|
let html =
|
'<tr class="standard-table"><td rowspan="' +
|
(rows.length + 1) +
|
'" class="label-cell">判定标准</td><td colspan="2" class="label-cell">级别</td><td colspan="3" class="label-cell">静态(cfu / 皿)</td><td colspan="3" class="label-cell">动态(cfu / 皿)</td><td colspan="2" class="label-cell">备注</td></tr>';
|
rows.forEach(function (row, index) {
|
html +=
|
'<tr class="standard-table"><td colspan="2">' +
|
escapeHtml(row.level) +
|
'</td><td colspan="3">' +
|
escapeHtml(row.static_limit) +
|
'</td><td colspan="3">' +
|
escapeHtml(row.dynamic_limit) +
|
'</td>';
|
if (index === 0) {
|
html +=
|
'<td colspan="2" rowspan="' +
|
rows.length +
|
'">' +
|
escapeHtml(row.remark || row.beizhu || '') +
|
'</td>';
|
}
|
html += '</tr>';
|
});
|
return html;
|
}
|
|
function generateFooterHTML() {
|
return (
|
generateStandardRowsHTML() +
|
'<tr><td class="label-cell">结论</td><td colspan="10"><span class="checkbox-line"><span class="check">' +
|
checked(isYes(templateData.jielun)) +
|
'符合规定</span><span class="check">' +
|
checked(isNo(templateData.jielun)) +
|
'不符合规定</span></span>' +
|
'</td></tr>' +
|
'<tr class="signature-row"><td class="label-cell">检测人/日期</td><td colspan="3">' +
|
escapeHtml(signatureText(signatures.operator)) +
|
'</td><td colspan="2" class="label-cell">记录人/日期</td><td colspan="2">' +
|
escapeHtml(signatureText(signatures.recorder)) +
|
'</td><td colspan="2" class="label-cell">复核人/日期</td><td>' +
|
escapeHtml(signatureText(signatures.reviewer)) +
|
'</td></tr>'
|
);
|
}
|
|
function generatePageHTML(chunk, pageNum, totalPages, isLastPage) {
|
return (
|
'<section class="page">' +
|
generateHeaderHTML(pageNum, totalPages) +
|
'<table class="main-table">' +
|
'<colgroup><col style="width:14.1%"><col style="width:1.9%"><col style="width:13.3%"><col style="width:4.1%"><col style="width:11.3%"><col style="width:2.1%"><col style="width:1.8%"><col style="width:16.1%"><col style="width:14.2%"><col style="width:2.6%"><col style="width:18.5%"></colgroup>' +
|
generateInfoRowsHTML() +
|
generateSampleRowsHTML(chunk) +
|
(isLastPage ? generateFooterHTML() : '') +
|
'</table>' +
|
'</section>'
|
);
|
}
|
|
function render() {
|
const chunks = [];
|
for (let i = 0; i < items.length; i += PAGE_SIZE) {
|
chunks.push(items.slice(i, i + PAGE_SIZE));
|
}
|
if (!chunks.length) chunks.push([]);
|
const totalPages = chunks.length;
|
document.getElementById('print-container').innerHTML = chunks
|
.map(function (chunk, index) {
|
return generatePageHTML(chunk, index + 1, totalPages, index === totalPages - 1);
|
})
|
.join('');
|
}
|
|
render();
|
</script>
|
</body>
|
</html>
|