Bläddra i källkod

生成soc卡word的模板

Zimo 1 dag sedan
förälder
incheckning
95f089b37f

+ 65 - 27
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/util/SafetyObservationCardGenerator.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.util;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.poi.util.Units;
 import org.apache.poi.xwpf.usermodel.*;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
@@ -12,21 +13,20 @@ import java.util.List;
 
 public class SafetyObservationCardGenerator {
 
-    public static void main(String[] args) {
+    // 核心入口:支持传入需要打勾的子项列表
+    public static void generateCard(List<String> checkedItems) {
         try (XWPFDocument document = new XWPFDocument();
              FileOutputStream out = new FileOutputStream("行为安全观察与沟通卡-数智化.docx")) {
 
-            // 1. 标题:替换为KERUI科瑞石油技术图片(核心修改)
+            // 1. 标题:替换为KERUI科瑞石油技术图片
             XWPFParagraph logoPara = document.createParagraph();
             logoPara.setAlignment(ParagraphAlignment.CENTER); // 图片居中
             XWPFRun logoRun = logoPara.createRun();
 
             // 读取本地图片并插入(替换为你的图片实际路径)
             String imagePath = "pic/keruishiyoujishu.png";
-// 获取resources下图片的输入流(无需关心物理路径)
             InputStream imageStream = new ClassPathResource(imagePath).getInputStream();
 
-// 然后将imageStream传入插入图片的方法(替代原有的FileInputStream)
             XWPFRun run = logoPara.createRun();
             run.addPicture(imageStream, XWPFDocument.PICTURE_TYPE_PNG, "keruishiyoujishu.png",
                     Units.toEMU(250), Units.toEMU(30)); // 宽高按需调整
@@ -48,11 +48,10 @@ public class SafetyObservationCardGenerator {
             XWPFTableCell titleCell = titleRow.getCell(0);
             setTitleStyle(titleCell, "行为安全观察与沟通卡", true, ParagraphAlignment.CENTER, "FFFFFF");
 
-            // 黄色提示栏 - 核心修改:单独设置提示文字样式
+            // 黄色提示栏
             XWPFTableRow tipRow = table.createRow();
             mergeCellsHorizontally(tipRow, 0, 2);
             XWPFTableCell tipCell = tipRow.getCell(0);
-            // 调用自定义的提示文字样式方法
             setTipTextStyle(tipCell, "若有任何不安全,请在小项前面□内打√。大项完全安全,请在大项后面□内打√。", true, ParagraphAlignment.LEFT, "FFFF00");
 
             // 行3:个人防护 | 规范操作 | 观察描述
@@ -72,7 +71,13 @@ public class SafetyObservationCardGenerator {
                     "□ 躯干\n" +
                     "□ 腿部和脚\n" +
                     "□ 其他 _______________";
+            // 处理个人防护子项勾选
+            ppeText = checkItemsInText(ppeText, checkedItems);
+
             String opText = "员工是否严格执行操作规程?\n□ 不按规定的方法操作\n□ 不采取安全措施进行操作\n□ 其他 _______________";
+            // 处理规范操作子项勾选
+            opText = checkItemsInText(opText, checkedItems);
+
             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");
@@ -85,7 +90,13 @@ public class SafetyObservationCardGenerator {
 
             XWPFTableRow row10 = table.createRow();
             String cmdText1 = "是否违章指挥?\n□ 指挥信号不正确/不清楚\n□ 多人指挥,信号不统一\n□ 非特殊情况下越权指挥\n□ 明知危险仍强令冒险作业\n□ 特殊作业前没有进行作业申请/风险分析\n□ 其他 _______________";
+            // 处理规范指挥子项勾选
+            cmdText1 = checkItemsInText(cmdText1, checkedItems);
+
             String posText1 = "人员站位是否安全?\n□ 碰撞到物体\n□ 被物体夹住/手扶握物体部位不正确\n□ 跌倒/坠落/陷入物体之中\n□ 被物体砸到\n□ 接触极高/极低温度/电流/电击\n□ 吸入/吸收/吞食有害物质\n□ 姿势不良/用力过度\n□ 其他 _______________";
+            // 处理人员位置子项勾选
+            posText1 = checkItemsInText(posText1, checkedItems);
+
             String safeText1 = "·观察到的安全行为或安全状态\n·鼓励安全行为或安全状态所采取的行动";
             setCellStyle(row10.getCell(0), cmdText1, false, ParagraphAlignment.LEFT, "FFFFFF");
             setCellStyle(row10.getCell(1), posText1, false, ParagraphAlignment.LEFT, "FFFFFF");
@@ -93,7 +104,6 @@ public class SafetyObservationCardGenerator {
 
             // 行6:规范指挥明细 | 人员位置明细 | 安全行为描述(后续垂直合并)
             XWPFTableRow row6 = table.createRow();
-            // ========== 核心修改1:设置row6行高(增高,示例:800缇 ≈ 40磅) ==========
             setRowHeight(row6, 1900);
             String cmdText = "";
             String posText = "";
@@ -104,7 +114,6 @@ public class SafetyObservationCardGenerator {
 
             // 行7:规范指挥明细 | 人员位置明细 | 安全行为描述(后续垂直合并)
             XWPFTableRow row7 = table.createRow();
-            // ========== 核心修改2:设置row7行高(降低,示例:200缇 ≈ 10磅) ==========
             setRowHeight(row7, 500);
             String cmdText2 = "";
             String posText2 = "";
@@ -121,9 +130,14 @@ public class SafetyObservationCardGenerator {
 
             // 行8:作业场所明细 | 空 | 不安全行为描述(后续垂直合并)
             XWPFTableRow row8 = table.createRow();
-//            mergeCellsHorizontally(row8, 0, 1);
             String houseText = "□ 作业场所杂乱\n□ 作业空间狭小\n□ 堵塞安全通道\n□ 地面滑(水/雨/雪/油污等)\n□ 物体/工具放置位置不当        \n□ 危险场所没有标志/标志不清\n□ 照明光线不良";
+            // 处理作业场所子项勾选
+            houseText = checkItemsInText(houseText, checkedItems);
+
             String secondText = "□ 带电装置带电部分裸露\n□ 设备无防护/防护装置不当\n□ 未工完料净场地清/垃圾未分类存放\n□ 通风不良/氧气含量未达标\n□ 其他 _______________";
+            // 处理作业场所子项勾选
+            secondText = checkItemsInText(secondText, checkedItems);
+
             String unsafeText = "";
             setCellStyle(row8.getCell(0), houseText, false, ParagraphAlignment.LEFT, "FFFFFF");
             setCellStyle(row8.getCell(1), secondText, false, ParagraphAlignment.LEFT, "FFFFFF");
@@ -133,10 +147,11 @@ public class SafetyObservationCardGenerator {
             XWPFTableRow footerRow = table.createRow();
             mergeCellsHorizontally(footerRow, 0, 2);
             String footerText = "观察区域: ____________  实施观察人员: ____________  被观察岗位:____________  \n被观察人员:□员工 □承包商 □供应商 日期: __________ 时间:___点___分到___点___分";
+            // 处理底部人员类型勾选(可选)
+            footerText = checkItemsInText(footerText, checkedItems);
             setCellStyle(footerRow.getCell(0), footerText, true, ParagraphAlignment.LEFT, "FFFFFF");
 
-            // 核心修复:垂直合并第三列的单元格(行3到行8的第三列)
-            // 行索引说明:table.getRow(2) = 行3(标题行是0,提示行是1),table.getRow(7) = 行8
+            // 垂直合并第三列的单元格
             mergeCellsVertically(table, 2, 4, 2);
             mergeCellsVertically(table, 5,7,0);
             mergeCellsVertically(table, 5,7,1);
@@ -149,13 +164,41 @@ public class SafetyObservationCardGenerator {
         }
     }
 
-    // ========== 新增:设置行高的工具方法(适配POI 5.2.5) ==========
+    // 核心工具方法:处理文本中的勾选框,匹配到checkedItems的子项则替换□为☑
+    private static String checkItemsInText(String originalText, List<String> checkedItems) {
+        if (checkedItems == null || checkedItems.isEmpty()) {
+            return originalText;
+        }
+        String processedText = originalText;
+        for (String item : checkedItems) {
+            // 匹配 "□ 子项内容" 格式,替换为 "☑ 子项内容"
+            String target = "□ " + item;
+            String replacement = "☑ " + item;
+            processedText = processedText.replace(target, replacement);
+        }
+        return processedText;
+    }
+
+    // 测试入口
+    public static void main(String[] args) {
+        // 示例:需要打勾的子项列表
+        List<String> checkedItems = ImmutableList.of(
+                "头部",                // 个人防护子项
+                "不按规定的方法操作", // 规范操作子项
+                "指挥信号不正确/不清楚", // 规范指挥子项
+                "碰撞到物体",         // 人员位置子项
+                "作业场所杂乱"        // 作业场所子项
+        );
+        generateCard(checkedItems);
+    }
+
+    // 设置行高的工具方法(适配POI 5.2.5)
     private static void setRowHeight(XWPFTableRow row, int heightInTwips) {
         CTRow ctTr = row.getCtRow();
         CTTrPr trPr = ctTr.getTrPr() == null ? ctTr.addNewTrPr() : ctTr.getTrPr();
         CTHeight trHeight = trPr.addNewTrHeight();
         trHeight.setVal(BigInteger.valueOf(heightInTwips));
-        trHeight.setHRule(STHeightRule.EXACT); // 强制使用固定行高(不自动适应内容)
+        trHeight.setHRule(STHeightRule.EXACT); // 强制使用固定行高
     }
 
     // 标题样式设置
@@ -174,7 +217,7 @@ public class SafetyObservationCardGenerator {
         setCellBorder(cell);
     }
 
-    // 新增:提示文字专属样式设置(增加左缩进+行间距)
+    // 提示文字专属样式设置(增加左缩进+行间距)
     private static void setTipTextStyle(XWPFTableCell cell, String text, boolean bold, ParagraphAlignment align, String bgColor) {
         clearCellContent(cell);
 
@@ -187,16 +230,15 @@ public class SafetyObservationCardGenerator {
         paragraph.setAlignment(align);
         paragraph.setSpacingAfter(100); // 段后间距(缇,1磅=20缇)
         paragraph.setSpacingBefore(100); // 段前间距
-        // 设置左缩进(示例:2字符缩进,1字符≈1440缇)
-        paragraph.setIndentationFirstLine(288);
+        paragraph.setIndentationFirstLine(288); // 左缩进2字符
 
         XWPFRun run = paragraph.createRun();
         run.setText(text.trim());
-        run.setFontSize(9);          // 设置字体大小为9号
-        run.setFontFamily("宋体"); // 设置字体为宋体
-        run.setBold(true);            // 加粗
-        run.setColor("003366");       // 设置字体颜色为深蓝色
-        run.setTextPosition(10);      // 行内文字垂直间距
+        run.setFontSize(9);
+        run.setFontFamily("宋体");
+        run.setBold(true);
+        run.setColor("003366");
+        run.setTextPosition(10);
 
         cell.setColor(bgColor);
         setCellBorder(cell);
@@ -221,11 +263,9 @@ public class SafetyObservationCardGenerator {
             paragraph.setSpacingBefore(0);
 
             // 关键:给包含□的行增加左缩进(2字符),普通行按需调整
-            if (line.startsWith("□")) {
-                // 1字符≈1440缇,2字符=2880缇,可根据需要调整
+            if (line.startsWith("□")||line.startsWith("☑")) {
                 paragraph.setIndentationFirstLine(288);
             } else {
-                // 非选择框行,缩进1字符
                 paragraph.setIndentationFirstLine(144);
             }
 
@@ -234,7 +274,6 @@ public class SafetyObservationCardGenerator {
             run.setFontSize(9);
             run.setFontFamily("宋体");
             run.setBold(bold);
-            // 行内文字垂直间距(上下间距)
             run.setTextPosition(12);
         }
 
@@ -295,14 +334,13 @@ public class SafetyObservationCardGenerator {
         }
     }
 
-    // 新增:垂直合并单元格
+    // 垂直合并单元格
     private static void mergeCellsVertically(XWPFTable table, int fromRow, int toRow, int col) {
         for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
             XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
             CTTcPr tcPr = cell.getCTTc().getTcPr() != null ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
             STMerge.Enum mergeVal = (rowIndex == fromRow) ? STMerge.RESTART : STMerge.CONTINUE;
             tcPr.addNewVMerge().setVal(mergeVal);
-            // 确保合并后边框正常
             setCellBorder(cell);
         }
     }