在java中读取Excel文件并生成WBS代码

niknxzdl  于 2023-06-25  发布在  Java
关注(0)|答案(1)|浏览(156)

我试图读取Excel文件到Java代码
文件作为分组行缩进我试图生成嵌套的工作休息结构分组行例如1.1.1
我用的是apache POi 3.7
这是密码

public class ExcelReaderforHierarchy {
    
     public static boolean importExcel() throws Exception {
         boolean ret= false;
            try {
                String a_fileName = "E:\\groupedRow.xls";
                FileInputStream w_In = new FileInputStream(a_fileName);
                // Load the workbook
                HSSFWorkbook workbook = new HSSFWorkbook(w_In);

                // Get the first sheet in the workbook
                Sheet sheet = workbook.getSheetAt(0);

                generateWBSCodes(sheet);

                ret = true;

                // Close the workbook and file input stream
              //  workbook.close();
              //  file.close();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
            return ret;
        }
      private static void generateWBSCodes(Sheet sheet) {
            int currentLevel = 0;
            int groupIndex = 1;

            // Iterate over the rows in the sheet
            for (Row row : sheet) {
                // Check if the row is grouped
                if (isGroupedRow(row)) {
                    currentLevel++;
                    groupIndex = 1;
                }

                // Generate and print the WBS code
                String wbsCode = generateWBSCode(currentLevel, groupIndex);
                System.out.println("Row: " + row.getRowNum() + ", WBS Code: " + wbsCode);

                // Increment group index for the next row
                groupIndex++;
            }
        }

        private static boolean isGroupedRow(Row row) {
            Cell cell = row.getCell(0);
            try {
                 System.out.println("cellval -" + cell.getStringCellValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
           
          
                HSSFCellStyle cellStyle = (HSSFCellStyle) cell.getCellStyle();
                if (cellStyle != null) {
                    short indentLevel = cellStyle.getIndention();
                    System.out.println("indentLevel -" + cellStyle.getIndention()); // THIS always returns 0
                    return indentLevel > 0;
                }
          
            return false;
        }

        private static String generateWBSCode(int level, int index) {
            StringBuilder wbsCodeBuilder = new StringBuilder();
            for (int i = 0; i < level; i++) {
                if (i > 0) {
                    wbsCodeBuilder.append(".");
                }
                wbsCodeBuilder.append(index);
            }
            return wbsCodeBuilder.toString();
        }
    }

问题是cellStyle.getIndention();总是返回0
因此,我无法检测它是否是分组行
我也没有得到任何错误…

qnakjoqk

qnakjoqk1#

使用比十年前的3.7版本更新的Apache POI版本将是一个好主意。
但我认为问题的原因是缩进单元格值的不同方式。
下面显示了两种可能性:
第一变体:

A3A4A5使用单元格样式格式单元格-对齐-水平:左(缩进)-缩进:1、2和3缩进。
1表示3个空格。参见https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.alignment?view=openxml-2.8.1
indent(缩进)整数值,其中增量1表示3个空格。指示单元格中文本缩进的空格数(普通样式字体)。
也可以使用开始功能区栏中的按钮
增加缩进



第二种变体:

A10A11A12使用前面的空格缩进。因此,A9:A12中的单元格值为:

User Project
   Home
      Project Profile
         Edit Project Status

当然,short indentLevel = cellStyle.getIndention();只能用于A3A4A5中使用的变体1。为了支持第二种变体,需要获取单元格值之前的空格计数。
完整示例:

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;

class ReadExcelCelllIndent {
    
 static short getIndention(Cell cell) {
  CellStyle cellStyle = cell.getCellStyle();
  short indentLevel = cellStyle.getIndention();
  if (indentLevel == 0) {
   if (cell.getCellType() == CellType.STRING) {
    String cellValue = cell.getStringCellValue();
    String lTrimCellValue = cellValue.replaceAll("^\\s*", "");  
    int precedingSpaces = cellValue.length() - lTrimCellValue.length(); 
    // https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.alignment?view=openxml-2.8.1
    // indent (Indent)  An integer value, where an increment of 1 represents 3 spaces. 
    indentLevel = (short)(precedingSpaces / 3);
   }   
  }
  return indentLevel;  
 }

 public static void main(String[] args) throws Exception {

  Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xls"));
  Sheet sheet = workbook.getSheetAt(0);
  for (Row row : sheet) {
   for (Cell cell : row) {
    System.out.print(cell.getAddress() + ":");    
    System.out.print(cell);    
    CellStyle cellStyle = cell.getCellStyle();
    short indentLevel = cellStyle.getIndention();
    System.out.print("; indention from CellStyle :" + indentLevel);    
    indentLevel = getIndention(cell) ;
    System.out.println("; indention from method :" + indentLevel);        
   }
  }
 }
}

代码使用当前的Apache POI 5.2.3。
另一方面,您的屏幕截图显示了分组的行,这些行也可用于确定编号级别。这称为行的大纲级别,与缩进无关。使用当前的ApachePOI版本,可以通过Row.getOutlineLevel获取行的大纲级别
再举一个完整的例子:

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;

class ReadExcelRowOutlineLevel {
    
 public static void main(String[] args) throws Exception {

  Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xls"));
  Sheet sheet = workbook.getSheetAt(0);
  for (Row row : sheet) {
   int outlineLevel = row.getOutlineLevel();
   for (Cell cell : row) {
    System.out.print(cell.getAddress() + ":");    
    System.out.print(cell);
    System.out.println("; outline level: " + outlineLevel);
   }
  }
 }
}

相关问题