Shell脚本生成多库Oracle RMAN备份HTML报表如何固定各列宽度
问题根因
你当前的实现逻辑每次循环查询数据库都会生成独立的完整HTML表格,不同表格的列宽会根据当前行的内容自动适配,因此合并展示时会出现列宽不一致的问题。
解决方案
你可以通过调整脚本逻辑,将所有查询结果整合到同一个表格内,同时添加全局CSS固定列宽,实现统一的展示效果,具体修改如下:
1. 核心修改逻辑
- 脚本初始化阶段生成完整的HTML头部,包含统一的CSS样式,固定每一列的宽度
- 仅在页面初始化时生成一次表头,后续循环仅提取数据行内容追加
- 所有查询完成后补充表格和HTML的闭合标签
2. 修改后的完整脚本
# 先初始化HTML文件,写入头部和CSS样式 HTML_FILE=${LOG_DIR}/RMAN_REPORT.html cat > ${HTML_FILE} << 'EOF' <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>RMAN备份任务报表</title> <style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ccc; padding: 8px; text-align: left; } /* 按列顺序固定宽度,可根据实际需求调整数值和单位 */ th:nth-child(1), td:nth-child(1) { width: 12%; } /* 数据库名 */ th:nth-child(2), td:nth-child(2) { width: 10%; } /* 打开模式 */ th:nth-child(3), td:nth-child(3) { width: 15%; } /* 开始时间 */ th:nth-child(4), td:nth-child(4) { width: 15%; } /* 结束时间 */ th:nth-child(5), td:nth-child(5) { width: 10%; } /* 输出大小 */ th:nth-child(6), td:nth-child(6) { width: 10%; } /* 状态 */ th:nth-child(7), td:nth-child(7) { width: 8%; } /* 备份类型 */ th:nth-child(8), td:nth-child(8) { width: 8%; } /* 星期 */ th:nth-child(9), td:nth-child(9) { width: 7%; } /* 耗时秒数 */ th:nth-child(10), td:nth-child(10) { width: 5%; } /* 耗时展示 */ th { background-color: #f2f2f2; } .status-completed { color: green; } .status-failed { color: red; } </style> </head> <body> <h2>RMAN备份任务最近3天报表</h2> <table> <thead> <tr> <th>数据库名</th> <th>打开模式</th> <th>开始时间</th> <th>结束时间</th> <th>输出大小(MB)</th> <th>状态</th> <th>备份类型</th> <th>星期</th> <th>耗时(秒)</th> <th>耗时展示</th> </tr> </thead> <tbody> EOF # 遍历数据库实例拉取数据 for SID in $(cat /home/oracle/rmanbackupreport_GG/scripts_GG/dblist); do echo $SID sqlplus -s username/\"PASSWORD\"@${SID} << EOF > ${LOG_DIR}/tmp_row.html set feed off term off trims on linesize 300 pages 0 echo off underline off heading off select '<tr><td>'||a.name||'</td>'|| '<td>'||a.open_mode||'</td>'|| '<td>'||to_char(j.start_time, 'yyyy-mm-dd hh24:mi:ss')||'</td>'|| '<td>'||to_char(j.end_time, 'yyyy-mm-dd hh24:mi:ss')||'</td>'|| '<td>'||round(j.output_bytes/1024/1024,2)||'</td>'|| case when j.status='COMPLETED' then '<td class="status-completed">'||j.status||'</td>' else '<td class="status-failed">'||j.status||'</td>' end || '<td>'||j.input_type||'</td>'|| '<td>'||decode(to_char(j.start_time, 'd'), 1, 'Sunday', 2, 'Monday', 3, 'Tuesday', 4, 'Wednesday', 5, 'Thursday', 6, 'Friday', 7, 'Saturday')||'</td>'|| '<td>'||j.elapsed_seconds||'</td>'|| '<td>'||j.time_taken_display||'</td></tr>' from V\$RMAN_BACKUP_JOB_DETAILS j,V\$DATABASE a where j.start_time > trunc(sysdate)-3 and j.input_type <> 'ARCHIVELOG' and j.session_stamp=(select max(session_stamp) from v\$RMAN_BACKUP_JOB_DETAILS j where j.start_time > trunc(sysdate)-7 and j.input_type <> 'ARCHIVELOG') / exit EOF # 过滤空行后追加到HTML文件的tbody里 grep -v '^$' ${LOG_DIR}/tmp_row.html >> ${HTML_FILE} rm -f ${LOG_DIR}/tmp_row.html done # 补充HTML闭合标签 cat >> ${HTML_FILE} << 'EOF' </tbody> </table> </body> </html> EOF # 清理旧的临时文件 rm -f ${LOG_DIR}/rman_job_status.txt
方案优势
- 所有数据都在同一个表格内,天然保证列宽统一
- CSS集中控制样式,后续调整列宽、配色都只需要修改样式部分即可
- 去掉了sqlplus自动生成的冗余HTML代码,文件体积更小,加载速度更快
内容的提问来源于stack exchange,提问作者Gaurav Gupta
相关产品推荐
相关产品推荐

