<!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;
|
display: inline-flex;
|
gap: 2mm;
|
white-space: nowrap;
|
}
|
|
.main-table td {
|
height: 7.2mm;
|
word-break: normal;
|
overflow-wrap: break-word;
|
}
|
|
.sample-header td {
|
font-weight: bold;
|
height: 8mm;
|
white-space: nowrap;
|
}
|
|
.sample-row td {
|
height: 7.2mm;
|
}
|
|
.standard-table td {
|
height: 7mm;
|
white-space: normal;
|
}
|
|
.particle-size {
|
white-space: nowrap;
|
}
|
|
.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 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) {
|
if (!item) {
|
return '<td></td><td></td><td></td><td></td>';
|
}
|
const pointName = value(item.quyangdian_mingcheng, item.weizhi_mingcheng, item.weizhi_bianhao);
|
return (
|
'<td>' +
|
escapeHtml(pointName) +
|
'</td><td>' +
|
escapeHtml(item.ceshi_jieguo) +
|
'</td><td>' +
|
escapeHtml(item.ceshi_jieguo_lijing) +
|
'</td><td><span class="check"><span>' +
|
checked(isYes(item.shifou_hege)) +
|
'是</span><span>' +
|
checked(isNo(item.shifou_hege)) +
|
'否</span></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(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 class="label-cell">检测区域</td><td colspan="3">' +
|
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 class="label-cell">测试状态</td><td colspan="3"><span class="checkbox-line"><span class="check">' +
|
checked(isStaticStatus()) +
|
'静态</span><span class="check">' +
|
checked(isDynamicStatus()) +
|
'动态</span></span></td><td class="label-cell">采样量/L</td><td colspan="3">' +
|
escapeHtml(header.quyangliang) +
|
'</td></tr>' +
|
'<tr><td colspan="2" class="label-cell">悬浮粒子计数器编号</td><td colspan="2">' +
|
escapeHtml(header.xuanfulizi_jishuqi_bianhao) +
|
'</td><td colspan="2" class="label-cell">校准有效期</td><td colspan="2">' +
|
escapeHtml(header.caiyangyi_jiaozhun_youxiaoqi || header.jiaozhun_youxiaoqi) +
|
'</td></tr>'
|
);
|
}
|
|
function generateSampleRowsHTML(chunk) {
|
let html =
|
'<tr class="sample-header"><td rowspan="2">取样点</td><td colspan="2">粒子数(p/m3)</td><td rowspan="2">是否合格</td><td rowspan="2">取样点</td><td colspan="2">粒子数(p/m3)</td><td rowspan="2">是否合格</td></tr>' +
|
'<tr class="sample-header"><td class="particle-size">≥0.5μm</td><td class="particle-size">≥5μm</td><td class="particle-size">≥0.5μm</td><td class="particle-size">≥5μm</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) + sampleCell(right) + '</tr>';
|
}
|
return html;
|
}
|
|
function generateStandardRowsHTML() {
|
const rows = standardRows.length
|
? standardRows
|
: [
|
{ level: 'A', static_limit_05: '3520', static_limit_5: '20', dynamic_limit_05: '3520', dynamic_limit_5: '20' },
|
{ level: 'B', static_limit_05: '3520', static_limit_5: '29', dynamic_limit_05: '352000', dynamic_limit_5: '2900' },
|
{ level: 'C', static_limit_05: '352000', static_limit_5: '2900', dynamic_limit_05: '3520000', dynamic_limit_5: '29000' },
|
{ level: 'D', static_limit_05: '3520000', static_limit_5: '29000', dynamic_limit_05: 'NA', dynamic_limit_5: 'NA' },
|
];
|
let html =
|
'<tr class="standard-table"><td rowspan="' +
|
(rows.length + 2) +
|
'" class="label-cell">判定标准</td><td rowspan="2" class="label-cell">级别</td><td colspan="2" class="label-cell">静态标准(p/m3)</td><td colspan="2" class="label-cell">动态标准(p/m3)</td><td colspan="2" rowspan="' +
|
(rows.length + 2) +
|
'" class="label-cell left">备注:</td></tr>' +
|
'<tr class="standard-table"><td class="particle-size">≥0.5μm</td><td class="particle-size">≥5μm</td><td class="particle-size">≥0.5μm</td><td class="particle-size">≥5μm</td></tr>';
|
rows.forEach(function (row) {
|
html +=
|
'<tr class="standard-table"><td>' +
|
escapeHtml(row.level) +
|
'</td><td>' +
|
escapeHtml(value(row.static_limit_05, row.static05, row.static_limit)) +
|
'</td><td>' +
|
escapeHtml(value(row.static_limit_5, row.static5)) +
|
'</td><td>' +
|
escapeHtml(value(row.dynamic_limit_05, row.dynamic05, row.dynamic_limit)) +
|
'</td><td>' +
|
escapeHtml(value(row.dynamic_limit_5, row.dynamic5)) +
|
'</td></tr>';
|
});
|
return html;
|
}
|
|
function generateFooterHTML() {
|
return (
|
generateStandardRowsHTML() +
|
'<tr><td class="label-cell">结论:</td><td colspan="7"><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 class="label-cell">复核人/日期</td><td colspan="3">' +
|
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:13%"><col style="width:12%"><col style="width:12%"><col style="width:13%"><col style="width:13%"><col style="width:12%"><col style="width:12%"><col style="width:13%"></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>
|