Prechádzať zdrojové kódy

复选框PDF文本对齐

xy 1 týždeň pred
rodič
commit
718d8c24a8

+ 41 - 3
src/main/java/com/grapecity/controller/GrapeCityController.java

@@ -319,14 +319,17 @@ public class GrapeCityController {
 
                 // 浮动图片
                 processFloatingImages(worksheet, data, fileBytes);
+
+                // 将复选框单元格转换为纯文本,避免PDF中勾选框与文字不在同一水平线
+                convertCheckboxCellsToText(worksheet);
             }
             PrintManager printManager = new PrintManager();
-            //Workbook.FontsFolderPath = this.fontsFolderPath;
             Workbook.FontProvider = new IFontProvider() {
                 @Override
                 public List<String> getFontFilePaths() {
                     return new ArrayList<>(Arrays.asList(
-                            "fonts/simsun.ttf"
+                            "fonts/simsun.ttf",
+                            "fonts/seguisym.ttf"
                     ));
                 }
 
@@ -400,7 +403,7 @@ public class GrapeCityController {
                             mergeArea.setBackgroundImage(mergedImage);
                         }
                     }
-                    // 复选框
+                    // 复选框:清空非"true"的值
                     if (range.getCellType() instanceof com.grapecity.documents.excel.CheckBoxCellType) {
                         if (!"true".equals(value)) {
                             range.setValue(null);
@@ -481,6 +484,41 @@ public class GrapeCityController {
         }
     }
 
+    /**
+     * 将 CheckBoxCellType 复选框转换为纯文本显示(勾选符号 + 文字),
+     * 避免 GcExcel PDF 渲染时勾选框与文字基线不齐的问题。
+     */
+    private void convertCheckboxCellsToText(IWorksheet worksheet) {
+        for (int r = 0; r < worksheet.getRowCount(); r++) {
+            for (int c = 0; c < worksheet.getColumnCount(); c++) {
+                IRange cell = worksheet.getRange(r, c);
+                if (!(cell.getCellType() instanceof CheckBoxCellType cbType)) {
+                    continue;
+                }
+                // 读取复选框状态和显示文字
+                Object val = cell.getValue();
+                boolean checked = "true".equals(val instanceof String ? val : String.valueOf(val));
+                String caption = cbType.getCaption();
+                if (caption == null || caption.isEmpty()) {
+                    caption = checked ? cbType.getTextTrue() : cbType.getTextFalse();
+                }
+
+                // 用勾选符号 + 文字替代 CheckBoxCellType
+                String displayText = checked ? "☑" : "☐";
+                if (caption != null && !caption.isEmpty()) {
+                    displayText += caption;
+                }
+
+                // 继承原单元格字体大小,确保勾选符号与文字大小一致
+                double fontSize = cell.getFont().getSize();
+                cell.setCellType(null);
+                cell.setValue(displayText);
+                cell.getFont().setSize(fontSize);
+                cell.setVerticalAlignment(VerticalAlignment.Center);
+            }
+        }
+    }
+
     /**
      * 处理续页:检查 copyConfig 配置,处理隐藏空页和自动生成续页
      * copyConfigJson 和 existingColCodes 由 pressure2 传入,newColCodes 通过参数返回给调用方

+ 40 - 1
src/main/java/com/grapecity/controller/PdfController.java

@@ -48,12 +48,16 @@ public class PdfController {
             worksheet.getPageSetup().setPaperSize(PaperSize.A4);
             worksheet.getPageSetup().setCenterHorizontally(true);
             worksheet.getPageSetup().setTopMargin(36); // 设置上边距为 36 磅(约 1.27 厘米)
+
+            // 将复选框转换为纯文本显示,避免PDF中勾选框与文字不在同一水平线
+            convertCheckboxCellsToText(worksheet);
         }
         Workbook.FontProvider = new IFontProvider() {
             @Override
             public List<String> getFontFilePaths() {
                 return new ArrayList<>(Arrays.asList(
-                        "fonts/simsun.ttf"
+                        "fonts/simsun.ttf",
+                        "fonts/seguisym.ttf"
                 ));
             }
 
@@ -116,4 +120,39 @@ public class PdfController {
         
         response.getOutputStream().write(byteArrayOutputStream.toByteArray());
     }
+
+    /**
+     * 将 CheckBoxCellType 复选框转换为纯文本显示(勾选符号 + 文字),
+     * 避免 GcExcel PDF 渲染时勾选框与文字基线不齐的问题。
+     */
+    private void convertCheckboxCellsToText(IWorksheet worksheet) {
+        IRange usedRange = worksheet.getUsedRange();
+        if (usedRange == null) return;
+        for (int r = 0; r < usedRange.getRowCount(); r++) {
+            for (int c = 0; c < usedRange.getColumnCount(); c++) {
+                IRange cell = worksheet.getRange(r, c);
+                if (!(cell.getCellType() instanceof CheckBoxCellType cbType)) {
+                    continue;
+                }
+                Object val = cell.getValue();
+                boolean checked = "true".equals(val instanceof String ? (String) val : String.valueOf(val));
+                String caption = cbType.getCaption();
+                if (caption == null || caption.isEmpty()) {
+                    caption = checked ? cbType.getTextTrue() : cbType.getTextFalse();
+                }
+
+                String displayText = checked ? "☑" : "☐";
+                if (caption != null && !caption.isEmpty()) {
+                    displayText += caption;
+                }
+
+                // 继承原单元格字体大小,确保勾选符号与文字大小一致
+                double fontSize = cell.getFont().getSize();
+                cell.setCellType(null);
+                cell.setValue(displayText);
+                cell.getFont().setSize(fontSize);
+                cell.setVerticalAlignment(VerticalAlignment.Center);
+            }
+        }
+    }
 }

BIN
src/main/resources/fonts/seguisym.ttf