fei
2 天以前 5d91a329768a2a86e01e4b9b6bc6a2b939b87adb
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtilManySheetFour.java
@@ -12,17 +12,16 @@
import com.ruoyi.common.utils.file.FileTypeUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -260,8 +259,11 @@
     * @throws IOException
     */
    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 设置文件名
        String fileName = UUID.randomUUID() + "_"  + ".xlsx";
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        this.init(list, sheetName, Excel.Type.EXPORT);
        exportExcel(response.getOutputStream());
    }
@@ -274,10 +276,21 @@
     * @return 结果
     * @throws IOException
     */
    /**
     * 对list数据源将其里面的数据导入到excel表单
     *
     * @param response  返回数据
     * @param list      导出数据集合
     * @return 结果
     * @throws IOException
     */
    public void exportExcelManySheet(HttpServletResponse response, List<ExcelExp> list, boolean includeQrCode, byte[] bt,
                                     List<String> sigArr, List<String> arrAn, String inquiryNumber, String caseTitle) throws IOException {
      //  response.setContentType("application/vnd.ms-excel");
      //  response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 设置文件名
        String fileName = UUID.randomUUID() + "_" + ".xlsx";
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        try {
            createWorkbook();
@@ -294,44 +307,77 @@
                int column = 0;
                if(index == 0) {
                    // 合并第一行的前5个单元格
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8));
                    // 必须先设置为true
                    // 页面布局设置
                    sheet.setAutobreaks(true);
                    sheet.setFitToPage(true);
                    // 获取打印设置
                    PrintSetup printSetup = sheet.getPrintSetup();
                    // 设置为1页宽度
                    printSetup.setFitWidth((short) 1);   // 宽度调整为1页
                    printSetup.setFitHeight((short) 0);  // 高度不限制
                    // 其他打印设置
                    printSetup.setPaperSize(PrintSetup.A4_PAPERSIZE);  // A4纸
                    printSetup.setLandscape(true);  // 纵向打印
                    // 创建行并设置高度
                     row = sheet.createRow(firow);
                    row.setHeight((short)(40 * 40));
                    //生成二维码
                    if(includeQrCode)
                    {
                        Cell cell = row.createCell(6);
                        row.setHeight((short)(55.8 * 20));
                        Cell cell = row.createCell(0);
//                        for(int cl = 1 ; cl <=8; cl++)
//                            cell = row.createCell(cl);
//
//
//                        for (int col = 4; col <= 7; col++) {
//                            row.getSheet().setColumnWidth(col, 15 * 256); // 每列15字符宽
                //        }
                        int margin = -40* 9525;
                        int mary = -11 * 9525;
                        XSSFClientAnchor anchor = new XSSFClientAnchor(
                                0,          // dx1
                                0,          // dy1
                                margin,     // dx2:右边界左移10像素
                                mary,          // dy2
                                (short)5,   // col1
                                0,          // row1
                                (short)9,   // col2
                                1          // row2
                        );
                        // 设置图片大小和位置
                        ClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) (cell.getColumnIndex()+1), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() +2),
                                cell.getRow().getRowNum() + 1);
                     //   ClientAnchor anchor = new XSSFClientAnchor(0, 0, 600, 150, (short)0, 0, (short)6, 1);
                    //   anchor.setDx2(488);
                    //   anchor.setDy2(10);
                   //     anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
                        // 计算居中位置
//                    int col1 = 0; // 中间列
//                    int col2 = col1 + 2;
//                    anchor.setCol1(col1);
//                    anchor.setCol2(col2);
//                    anchor.setDx1(100);
//                    anchor.setDy1(0);
//                    anchor.setDx2(255); // 宽度
//                    anchor.setDy2(255); // 高度
                        anchor.setRow1(1);
                        anchor.setRow2(1);
                        byte[] data = bt;
                        anchor.setDx1(2400000);
                        anchor.setDy1(-10);
                        anchor.setDy2(-800000);
                        // 计算居中位置
//                        int col1 = 4; // 中间列
//                        int col2 = col1 + 3;
//                        anchor.setCol1(col1);
//                        anchor.setCol2(col2);
//                        anchor.setRow1(0);
//                        anchor.setRow2(1);
                        byte[] data = bt;
                        // 获取图片原始尺寸
                        BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
                        double widthInEMU = image.getWidth() * 9525 * 0.2;
                        double heightInEMU = image.getHeight() * 9525;
//                        double widthInEMU = image.getWidth() * 9525 * 0.2;
//                        double heightInEMU = image.getHeight() * 9525;
                        // 设置图片原始尺寸
                        anchor.setDx2(-100000); // 原始宽度
                    //    anchor.setDx2(-100000); // 原始宽度
                        //   anchor.setDy2((int)heightInEMU); // 原始高度
//anchor.setCol1(5); // 从第6列开始显示
//anchor.setCol2(10); // 到第11列结束
@@ -345,12 +391,16 @@
                        firow = firow + 1;
                        row = sheet.createRow(firow);
                    }
                  //  sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 7));
                    else
                        row.setHeight((short)(33 * 20));
                  //  sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8));
                    //  sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 7));
                    if(firow==1)
                    {
                        sheet.addMergedRegion(new CellRangeAddress(firow, firow, 0, 8));
                        // 创建行并设置高度
                        row.setHeight((short)(20 * 20));
                        row.setHeight((short)(33 * 20));
                    }
                    Cell titleCell = row.createCell(0);
                    titleCell.setCellValue("文件材料移交目录清单(卷内级)");
@@ -358,26 +408,106 @@
                    CellStyle style = wb.createCellStyle();
                    Font font = wb.createFont();
                    font.setBold(true);
                    font.setFontHeightInPoints((short) 18);
                    font.setFontName("宋体");
                    style.setFont(font);
                    style.setVerticalAlignment(VerticalAlignment.CENTER);
                    style.setAlignment(HorizontalAlignment.CENTER);
                    titleCell.setCellStyle(style);
                    firow = firow + 1;
                    row = sheet.createRow(firow);
               //
                    row.createCell(0).setCellValue("发文号:");
                    sheet.addMergedRegion(new CellRangeAddress(firow, firow, 1, 3));
                    row.createCell(1).setCellValue(inquiryNumber);
                    row.createCell(4).setCellValue("案卷题名:");
                    sheet.addMergedRegion(new CellRangeAddress(firow, firow, 5, 9));
                    //   row.createCell(4).setCellValue("档号:");
                    //拿到档号
                    row.createCell(5).setCellValue(caseTitle);
                    // 将固定行高改为自动行高,以便内容能完整显示在合并区域
                    row.setHeight((short)(27.6*20));
                    //
                    CellStyle style1 = wb.createCellStyle();
                    style1.setAlignment(HorizontalAlignment.RIGHT);
                    style1.setVerticalAlignment(VerticalAlignment.TOP);
                    Font font1 = wb.createFont();
                    font1.setBold(true);
                    font1.setFontHeightInPoints((short) 12);
                    font1.setFontName("宋体");
                    style1.setFont(font1);
                    Cell cell2 = row.createCell(0);
                    cell2.setCellValue("发文号:");
                    cell2.setCellStyle(style1);
                    // 合并第1-3列
                    int startCol1 = 1;
                    int endCol1 = 2;
                    sheet.addMergedRegion(new CellRangeAddress(firow, firow, startCol1, endCol1));
                    // 设置所有合并单元格的样式
                    for (int col = startCol1; col <= endCol1; col++) {
                        Cell mergedCell = row.createCell(col);
                        mergedCell.setCellStyle(style1);
                    }
                    // 只在起始单元格设置数据
                    CellStyle style2 = wb.createCellStyle();
                    style2.setAlignment(HorizontalAlignment.LEFT);
                    style2.setVerticalAlignment(VerticalAlignment.TOP);
                    Font font2 = wb.createFont();
                    font2.setFontHeightInPoints((short) 11);
                    font2.setFontName("宋体");
                    style2.setFont(font2);
                    Cell inquiryCell = row.getCell(startCol1);
                    inquiryCell.setCellStyle(style2);
                    inquiryCell.setCellValue(inquiryNumber);
                    Cell cell1 = row.createCell(3);
                    cell1.setCellValue("案卷题名:");
                    cell1.setCellStyle(style1);
                    // 创建一个新的样式用于案卷题名合并单元格
                    CellStyle mergedCellStyle = wb.createCellStyle();
                    mergedCellStyle.cloneStyleFrom(style1); // 继承原有样式
                    mergedCellStyle.setAlignment(HorizontalAlignment.LEFT); // 改为左对齐
                    mergedCellStyle.setWrapText(true); // 启用自动换行
                    //mergedCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
                    // 合并第5-8列
                    int startCol = 4;
                    int endCol = 8;
                    // 先创建所有需要的单元格并设置样式
                    for (int col = startCol; col <= endCol; col++) {
                        Cell mergedCell = row.createCell(col);
                        mergedCell.setCellStyle(mergedCellStyle);
                    }
                    // 然后执行合并操作
                    sheet.addMergedRegion(new CellRangeAddress(firow, firow, startCol, endCol));
                    // 只在起始单元格设置数据
                    Cell getCas = row.getCell(startCol);
                    style2.setWrapText(true); // 启用自动换行
                    getCas.setCellStyle(style2);
                    getCas.setCellValue(caseTitle);
                    // 只在起始单元格设置数据
                    //ces.setCellValue(caseTitle);
                    // 设置自动换行
//                    row = sheet.createRow(2);
//                    row.createCell(0).setCellValue("案卷题名:");
                    // 设置自动换行
//                    row = sheet.createRow(2);
//                    row.createCell(0).setCellValue("案卷题名:");
                    firow = firow + 1;
                    row = sheet.createRow(firow);
                    // 设置表头高度为43.2
                    row.setHeight((short)(43.2*20));
                    System.out.println("++++++++++++++++++++++++++---------++++++++++++");
                    System.out.println(firow);
                    column = 0;
@@ -385,6 +515,8 @@
                    // 普通sheet处理
                 //   recordId = (DocumentMaterialsVo)list.get(0)
                    row = sheet.createRow(0);
                    // 设置表头高度为43.2
                    row.setHeight((short)(43.2*20));
                    column = 0;
                }
//                // 产生一行
@@ -402,19 +534,46 @@
                //写入签名
                System.out.println(list.get(0).getDataset().size()+"aaaaaaaaaaaaaaaaaaa0999");
                row = sheet.createRow(list.get(0).getDataset().size()+4);
                row = sheet.createRow(list.get(0).getDataset().size()+5);
                //
                                    CellStyle style4 = wb.createCellStyle();
                    Font font4 = wb.createFont();
                    font4.setBold(true);
                    font4.setFontHeightInPoints((short) 12);
                    font4.setFontName("宋体");
                    style4.setFont(font4);
                int in = 0 ;
                for(int i = 0; i < sigArr.size(); i++) {
                    row.createCell(in).setCellValue(sigArr.get(i));
                    in = in + 3;
                for (String s : sigArr) {
                    Cell clr = row.createCell(in);
                    System.out.println(s);
                    clr.setCellStyle(style4);
                    clr.setCellValue(s);
                    in = in + 2;
                }
                System.out.println(in);
            //    row = sheet.createRow(0);
               // row = sheet.createRow(list.get(0).getDataset().size() + 7);
                //写入注释
                for(int i = 0; i < arrAn.size();i++) {
                    row = sheet.createRow(list.get(0).getDataset().size() + 5+i);
                    int ri = list.get(0).getDataset().size() + 5+i;
                   // System.out.println(arrAn.get(i));
                    row = sheet.createRow(list.get(0).getDataset().size() + 7+i);
                    int ri = list.get(0).getDataset().size() + 7+i;
                    sheet.addMergedRegion(new CellRangeAddress(ri, ri, 0, 3));
                    if(i==0)
                        row.createCell(0).setCellValue("注:    "+(i+1)+"、"+arrAn.get(i));
                    else
                        row.createCell(0).setCellValue("       "+(i+1)+"、"+arrAn.get(i));
                    row.createCell(0).setCellValue(i+1+"、"+arrAn.get(i));
                }
            }
@@ -447,8 +606,11 @@
     * @return 结果
     */
    public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 设置文件名
        String fileName = UUID.randomUUID() + "_"  + ".xlsx";
        response.setHeader("Content-Disposition", "attachment; filename=" );
        this.init(null, sheetName, Excel.Type.IMPORT);
        exportExcel(response.getOutputStream());
    }
@@ -549,7 +711,7 @@
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font dataFont = wb.createFont();
        dataFont.setFontName("Arial");
        dataFont.setFontName("宋体");
        dataFont.setFontHeightInPoints((short) 10);
        style.setFont(dataFont);
        styles.put("data", style);
@@ -574,9 +736,9 @@
                    style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                }*/
                Font headerFont = wb.createFont();
                headerFont.setFontName("Arial");
                headerFont.setFontHeightInPoints((short) 10);
                headerFont.setBold(false);
                headerFont.setFontName("宋体");
                headerFont.setFontHeightInPoints((short) 11);
                headerFont.setBold(true);
                headerFont.setColor(excel.headerColor().index);
                style.setFont(headerFont);
                headerStyles.put(key, style);
@@ -590,7 +752,7 @@
        // 设置单元格内容自动换行
        style.setWrapText(true);
        Font totalFont = wb.createFont();
        totalFont.setFontName("Arial");
        totalFont.setFontName("宋体");
        totalFont.setFontHeightInPoints((short) 10);
        style.setFont(totalFont);
        styles.put("total", style);
@@ -647,7 +809,7 @@
        } else if (Excel.ColumnType.NUMERIC == attr.cellType()) {
            cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
        } else if (Excel.ColumnType.IMAGE == attr.cellType()) {
            ClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
            ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
                    cell.getRow().getRowNum() + 1);
            String imagePath = Convert.toStr(value);
            if (StringUtils.isNotEmpty(imagePath)) {
@@ -694,12 +856,12 @@
        // 如果设置了提示信息则鼠标放上去提示.
        if (StringUtils.isNotEmpty(attr.prompt())) {
            // 这里默认设了2-101列提示.
            setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column);
            setCellPrompt(sheet, "", attr.prompt(), 1, 100, column, column);
        }
        // 如果设置了combo属性则本列只能选择不能输入
        if (attr.combo().length > 0) {
            // 这里默认设了2-101列只能选择不能输入.
            setHSSFValidation(sheet, attr.combo(), 1, 100, column, column);
            setCellValidation(sheet, attr.combo(), 1, 100, column, column);
        }
    }
@@ -710,7 +872,7 @@
        Cell cell = null;
        try {
            // 设置行高为自动调整
            row.setHeight((short) -1);
           // row.setHeight((short) -1);
            // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
            if (attr.isExport()) {
                // 创建cell
@@ -725,7 +887,13 @@
                } else if (align == HorizontalAlignment.RIGHT) {
                    styleKey = "data3";
                }
                cell.setCellStyle(styles.get(styleKey));
                // 获取并修改样式
                CellStyle style = styles.get(styleKey);
                Workbook workbook = row.getSheet().getWorkbook();
                CellStyle newStyle = workbook.createCellStyle();
                newStyle.cloneStyleFrom(style);
                newStyle.setWrapText(true); // 关键:启用自动换行
                cell.setCellStyle(newStyle);
                // 用于读取对象中的属性
                Object value = getTargetValue(vo, field, attr);
@@ -742,6 +910,7 @@
                    // 设置列类型
                    setCellVo(value, attr, cell);
                }
                adjustRowHeightAfterSetValue(row, cell, value);
                addStatisticsData(column, Convert.toStr(value), attr);
            }
        } catch (Exception e) {
@@ -749,9 +918,67 @@
        }
        return cell;
    }
    /**
     * 设置值后调整行高
     */
    private void adjustRowHeightAfterSetValue(Row row, Cell cell, Object value) {
        if (value == null) return;
        String text = value.toString();
        Sheet sheet = row.getSheet();
        // 1. 计算自动高度(基于内容)
        short autoHeight = calculateSimpleAutoHeight(text, cell);
        // 2. 获取当前行高
        short currentHeight = row.getHeight();
        if (currentHeight == -1) {
            currentHeight = sheet.getDefaultRowHeight();
        }
        // 3. 使用较大的高度(自动计算的高度或当前高度)
        short baseHeight = (short) Math.max(currentHeight, autoHeight);
        System.out.println(baseHeight+"aaaaaaaaatttttttt");
        // 4. 在基础上增加额外高度(100单位 = 5点)
        short extraHeight = 80;
        short newHeight = (short) (baseHeight + extraHeight);
        // 5. 限制最大高度
        short maxHeight = (short) 4000; // 100点
        row.setHeight((short) Math.min(maxHeight,newHeight));
    }
    /**
     * 设置 POI HSSFSheet 单元格提示
     * 简化的自动高度计算
     */
    private short calculateSimpleAutoHeight(String text, Cell cell) {
        if (text == null || text.isEmpty()) return 0;
        Sheet sheet = cell.getSheet();
        int colIndex = cell.getColumnIndex();
        // 获取列宽(字符数)
        int colWidthChars = sheet.getColumnWidth(colIndex) / 256;
        if (colWidthChars <= 0) colWidthChars = 10;
        // 计算文本行数
        int lines = 1;
        if (text.contains("\n")) {
            // 有显式换行
            String[] parts = text.split("\n");
            for (String part : parts) {
                lines += Math.max(1, (int) Math.ceil(part.length() * 1.5 / colWidthChars));
            }
        } else {
            // 自动换行
            lines = (int) Math.ceil(text.length() * 1.5 / colWidthChars);
        }
        // 每行高度:假设18点(360 POI单位)
        return (short) (lines * 360);
    }
    /**
     * 设置单元格提示
     *
     * @param sheet         表单
     * @param promptTitle   提示标题
@@ -761,7 +988,7 @@
     * @param firstCol      开始列
     * @param endCol        结束列
     */
    public void setHSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,
    public void setCellPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,
                              int firstCol, int endCol) {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = helper.createCustomConstraint("DD1");
@@ -783,7 +1010,7 @@
     * @param endCol   结束列
     * @return 设置好的sheet.
     */
    public void setHSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) {
    public void setCellValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // 加载下拉列表内容
        DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);
@@ -792,7 +1019,7 @@
        // 数据有效性对象
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        // 处理Excel兼容性问题
        if (dataValidation instanceof HSSFDataValidation) {
        if (dataValidation instanceof XSSFDataValidation) {
            dataValidation.setSuppressDropDownArrow(false);
            dataValidation.setShowErrorBox(true);
        }
@@ -991,7 +1218,7 @@
     * 创建一个工作簿
     */
    public void createWorkbook() {
        this.wb = new HSSFWorkbook();
        this.wb = new XSSFWorkbook();
    }
    /**
@@ -1061,3 +1288,18 @@
        return val;
    }
}