Sfoglia il codice sorgente

生成soc卡word的模板

Zimo 1 giorno fa
parent
commit
de202fc812

+ 214 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/util/SafetyObservationCardGenerator.java

@@ -0,0 +1,214 @@
+package cn.iocoder.yudao.module.pms.util;
+
+import org.apache.poi.xwpf.usermodel.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+
+import java.io.FileOutputStream;
+import java.util.List;
+
+public class SafetyObservationCardGenerator {
+
+    public static void main(String[] args) {
+        try (XWPFDocument document = new XWPFDocument();
+             FileOutputStream out = new FileOutputStream("行为安全观察与沟通卡-数智化.docx")) {
+
+            // 1. 标题:科瑞石油技术
+            XWPFParagraph logoPara = document.createParagraph();
+            logoPara.setAlignment(ParagraphAlignment.CENTER);
+            XWPFRun logoRun = logoPara.createRun();
+            logoRun.setText("KERUI科瑞石油技术");
+            logoRun.setBold(true);
+            logoRun.setFontSize(20);
+            logoRun.setFontFamily("Arial");
+            logoRun.setColor("0047AB");
+
+            document.createParagraph();
+
+            // 2. 创建表格
+            XWPFTable table = document.createTable(1, 3);
+            table.setWidth("100%");
+            table.removeRow(0);
+
+            // 标题行(文字浅蓝色)
+            XWPFTableRow titleRow = table.createRow();
+            mergeCellsHorizontally(titleRow, 0, 2);
+            XWPFTableCell titleCell = titleRow.getCell(0);
+            setTitleStyle(titleCell, "行为安全观察与沟通卡", true, ParagraphAlignment.CENTER, "FFFFFF");
+
+            // 黄色提示栏
+            XWPFTableRow tipRow = table.createRow();
+            mergeCellsHorizontally(tipRow, 0, 2);
+            XWPFTableCell tipCell = tipRow.getCell(0);
+            setCellStyle(tipCell, "若有任何不安全,请在小项前面□内打√。大项完全安全,请在大项后面□内打√。", false, ParagraphAlignment.LEFT, "FFFF00");
+
+            // 行3:个人防护 | 规范操作 | 观察描述
+            XWPFTableRow headerRow1 = table.createRow();
+            setCellStyle(headerRow1.getCell(0), "个人防护□", true, ParagraphAlignment.LEFT, "DCE6F1");
+            setCellStyle(headerRow1.getCell(1), "规范操作□", true, ParagraphAlignment.LEFT, "DCE6F1");
+            setCellStyle(headerRow1.getCell(2), "观察描述:", true, ParagraphAlignment.LEFT, "DCE6F1");
+
+            // 行4(修复换行:改用新段落实现)
+            XWPFTableRow row4 = table.createRow();
+            String ppeText = "个人防护用品是否齐全、规范?\n" +
+                    "□ 头部\n" +
+                    "□ 脸部及眼部\n" +
+                    "□ 听力保护\n" +
+                    "□ 呼吸系统\n" +
+                    "□ 胳膊和手\n" +
+                    "□ 躯干\n" +
+                    "□ 腿部和脚\n" +
+                    "□ 其他 _______________";
+            String opText = "员工是否严格执行操作规程?\n□ 不按规定的方法操作\n□ 不采取安全措施进行操作\n□ 其他 _______________";
+            setCellStyle(row4.getCell(0), ppeText, false, ParagraphAlignment.LEFT, "FFFFFF");
+            setCellStyle(row4.getCell(1), opText, false, ParagraphAlignment.LEFT, "FFFFFF");
+            setCellStyle(row4.getCell(2), "", false, ParagraphAlignment.LEFT, "E6EBF5");
+
+            // 行5
+            XWPFTableRow headerRow2 = table.createRow();
+            setCellStyle(headerRow2.getCell(0), "规范指挥□", true, ParagraphAlignment.LEFT, "DCE6F1");
+            setCellStyle(headerRow2.getCell(1), "人员位置□", true, ParagraphAlignment.LEFT, "DCE6F1");
+            setCellStyle(headerRow2.getCell(2), "", false, ParagraphAlignment.LEFT, "E6EBF5");
+
+            // 行6
+            XWPFTableRow row6 = table.createRow();
+            String cmdText = "是否违章指挥?\n□ 指挥信号不正确/不清楚\n□ 多人指挥,信号不统一\n□ 非特殊情况下越权指挥\n□ 明知危险仍强令冒险作业\n□ 特殊作业前没有进行作业申请/风险分析\n□ 其他 _______________";
+            String posText = "人员站位是否安全?\n□ 碰撞到物体\n□ 被物体夹住/手扶握物体部位不正确\n□ 跌倒/坠落/陷入物体之中\n□ 被物体砸到\n□ 接触极高/极低温度/电流/电击\n□ 吸入/吸收/吞食有害物质\n□ 姿势不良/用力过度\n□ 其他 _______________";
+            String safeText = "-观察到的安全行为或安全状态\n-鼓励安全行为或安全状态所采取的行动";
+            setCellStyle(row6.getCell(0), cmdText, false, ParagraphAlignment.LEFT, "FFFFFF");
+            setCellStyle(row6.getCell(1), posText, false, ParagraphAlignment.LEFT, "FFFFFF");
+            setCellStyle(row6.getCell(2), safeText, false, ParagraphAlignment.LEFT, "E6EBF5");
+
+            // 行7
+            XWPFTableRow headerRow3 = table.createRow();
+            mergeCellsHorizontally(headerRow3, 0, 1);
+            setCellStyle(headerRow3.getCell(0), "作业场所□", true, ParagraphAlignment.LEFT, "DCE6F1");
+            setCellStyle(headerRow3.getCell(2), "", false, ParagraphAlignment.LEFT, "E6EBF5");
+
+            // 行8
+            XWPFTableRow row8 = table.createRow();
+            mergeCellsHorizontally(row8, 0, 1);
+            String houseText = "作业场所、工作环境是否存在不安全状态或其他安全隐患?\n□ 作业场所杂乱                □ 带电装置带电部分裸露\n□ 作业空间狭小                □ 设备无防护/防护装置不当\n□ 堵塞安全通道                □ 未工完料净场地清/垃圾未分类存放\n□ 地面滑(水/雨/雪/油污等)    □ 通风不良/氧气含量未达标\n□ 物体/工具放置位置不当        □ 其他 _______________\n□ 危险场所没有标志/标志不清\n□ 照明光线不良";
+            String unsafeText = "-观察到的不安全行为或不安全状态\n-即刻的纠正行动\n-预防再发生的行动";
+            setCellStyle(row8.getCell(0), houseText, false, ParagraphAlignment.LEFT, "FFFFFF");
+            setCellStyle(row8.getCell(2), unsafeText, false, ParagraphAlignment.LEFT, "E6EBF5");
+
+            // 底部信息
+            XWPFTableRow footerRow = table.createRow();
+            mergeCellsHorizontally(footerRow, 0, 2);
+            String footerText = "观察区域: _______________   实施观察人员: _______________   被观察岗位:_______________\n被观察人员: □员工  □承包商 □供应商   日期: _______________   时间:____点____分到____点____分";
+            setCellStyle(footerRow.getCell(0), footerText, false, ParagraphAlignment.LEFT, "FFFFFF");
+
+            document.write(out);
+            System.out.println("生成成功:行为安全观察与沟通卡-数智化.docx");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    // ====================== 标题专用:文字浅蓝色 ======================
+    private static void setTitleStyle(XWPFTableCell cell, String text, boolean bold, ParagraphAlignment align, String bgColor) {
+        clearCellContent(cell);
+
+        XWPFParagraph para = cell.addParagraph();
+        para.setAlignment(align);
+        XWPFRun run = para.createRun();
+        run.setText(text);
+        run.setFontSize(14);
+        run.setFontFamily("宋体");
+        run.setBold(bold);
+        run.setColor("4472C4"); // 标题文字浅蓝色
+        cell.setColor(bgColor);
+        setCellBorder(cell);
+    }
+
+    // ====================== 修复换行:每行创建独立段落 ======================
+    private static void setCellStyle(XWPFTableCell cell, String text, boolean bold, ParagraphAlignment align, String bgColor) {
+        // 安全清空单元格内容
+        clearCellContent(cell);
+
+        // 设置单元格垂直对齐为顶部
+        CTTcPr tcPr = cell.getCTTc().getTcPr() != null ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
+        CTVerticalJc vAlign = tcPr.addNewVAlign();
+        vAlign.setVal(STVerticalJc.TOP);
+
+        // 按换行符分割,每行创建一个新段落(确保换行生效)
+        String[] lines = text.split("\n");
+        for (String line : lines) {
+            XWPFParagraph paragraph = cell.addParagraph();
+            paragraph.setAlignment(align);
+            paragraph.setSpacingAfter(0); // 取消段落间距
+            paragraph.setSpacingBefore(0);
+
+            XWPFRun run = paragraph.createRun();
+            run.setText(line.trim()); // 去除行首尾空格(可选)
+            run.setFontSize(10);
+            run.setFontFamily("宋体");
+            run.setBold(bold);
+            // 取消行间距,避免换行后间距过大
+            run.setTextPosition(0);
+        }
+
+        // 处理空文本情况(至少创建一个空段落)
+        if (lines.length == 0 && text.isEmpty()) {
+            XWPFParagraph paragraph = cell.addParagraph();
+            paragraph.setAlignment(align);
+            XWPFRun run = paragraph.createRun();
+            run.setText("");
+        }
+
+        cell.setColor(bgColor);
+        setCellBorder(cell);
+    }
+
+    /**
+     * 安全清空单元格内容(解决 UnmodifiableCollection 问题)
+     */
+    private static void clearCellContent(XWPFTableCell cell) {
+        // 先移除所有段落
+        List<XWPFParagraph> paragraphs = cell.getParagraphs();
+        while (paragraphs != null && !paragraphs.isEmpty()) {
+            cell.removeParagraph(0);
+            paragraphs = cell.getParagraphs(); // 重新获取列表(避免并发修改)
+        }
+        // 移除所有嵌套表格
+        List<XWPFTable> tables = cell.getTables();
+        while (tables != null && !tables.isEmpty()) {
+            cell.removeTable(0);
+            tables = cell.getTables();
+        }
+    }
+
+    private static void setCellBorder(XWPFTableCell cell) {
+        CTTcPr tcPr = cell.getCTTc().getTcPr() != null ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
+        CTTcBorders borders = tcPr.getTcBorders() != null ? tcPr.getTcBorders() : tcPr.addNewTcBorders();
+
+        // 设置边框样式和颜色(确保边框显示)
+        STBorder.Enum borderStyle = STBorder.SINGLE;
+        borders.addNewTop().setVal(borderStyle);
+        borders.getTop().setColor("000000"); // 黑色边框
+        borders.addNewBottom().setVal(borderStyle);
+        borders.getBottom().setColor("000000");
+        borders.addNewLeft().setVal(borderStyle);
+        borders.getLeft().setColor("000000");
+        borders.addNewRight().setVal(borderStyle);
+        borders.getRight().setColor("000000");
+    }
+
+    private static void mergeCellsHorizontally(XWPFTableRow row, int fromCol, int toCol) {
+        // 确保列数足够
+        while (row.getTableCells().size() <= toCol) {
+            row.createCell();
+        }
+
+        // 第一个单元格设为RESTART
+        CTTcPr firstPr = row.getCell(fromCol).getCTTc().getTcPr() != null ? row.getCell(fromCol).getCTTc().getTcPr() : row.getCell(fromCol).getCTTc().addNewTcPr();
+        firstPr.addNewHMerge().setVal(STMerge.RESTART);
+
+        // 后续单元格设为CONTINUE
+        for (int i = fromCol + 1; i <= toCol; i++) {
+            CTTcPr pr = row.getCell(i).getCTTc().getTcPr() != null ? row.getCell(i).getCTTc().getTcPr() : row.getCell(i).getCTTc().addNewTcPr();
+            pr.addNewHMerge().setVal(STMerge.CONTINUE);
+        }
+    }
+}