如何使用 Apache POI 在 Excel 中隐藏 Un-used 行和列

How to HIDE Un-used Rows and Columns in Excel Using Apache POI

标题说明了一切 -- 需要隐藏包含我的数据的行和列之外的所有行和列。

我尝试了几种选择:

  1. How to hide the following Un-used rows in Excel sheet using Java Apache POI?
  2. Permanently Delete Empty Rows Apache POI using JAVA in Excel Sheet
  3. How to hide the following Un-used rows in Excel sheet using Java Apache POI?

但是这些从来没有产生预期的效果。我正在使用 apache poi 版本 4.1.1

请参阅以下屏幕截图,其中显示了我拥有的 excel 格式与我想要的格式。 (由于我是 Whosebug 的新手,它不允许我直接嵌入图片。很奇怪我知道。)

What I have

What I need

标记第一个“外部”列,按住 CTRL + SHIFT 然后向右箭头。然后,应突出显示所有列。右击,select“隐藏”。

对行重复相同的操作,select 数据之外的第一行,按住 CTRL + SHIFT 并按向下箭头

祝你好运!^_^

apache poi 的高级 类 直到现在才提供隐藏未使用的行和列。

隐藏未使用的行是 Office Open XML 的 sheet 格式属性中的一项设置,XSSF (*.xlsx) 的格式。默认情况下定义了如何处理行。例如默认行高。但也可以设置行默认为零高度。因此只有使用过的行,其单元格具有内容或格式是可见的。由于 apache poi 没有设置 SheetFormatPr.setZeroHeight 的方法,我们需要使用底层 org.openxmlformats.schemas.spreadsheetml.x2006.main.* 类.

HSSF (*.xls) 的二进制 BIFF 格式中,隐藏未使用的行是工作 sheet 记录中的 DEFAULTROWHEIGHT 记录中的设置溪流。可以设置选项标志。选项标志 0x0002 表示隐藏未使用的行。要使用 apache poi 进行设置,我们需要访问 org.apache.poi.hssf.record.DefaultRowHeightRecord。这只能从 InternalSheet.

得到

可以使用 Sheet.setColumnHidden 隐藏列,但仅限于单个列。所以要隐藏 100 列,需要调用 Sheet.setColumnHidden 100 次。

Excel 还提供从最小列到最大列的列范围设置。但是 Apache poi 没有为此提供高级方法。

使用 XSSF (Office Open XML) 我们需要 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols 来获取或设置具有适当最小值和最大值以及 setHidden(true)org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol

使用 HSSF (BIFF) 我们需要获取或设置 COLINFO 记录 from/to 作品sheet 的记录流,其中包含适当的最小值和最大值以及 setHidden(true).

以下完整示例显示了上述代码示例。它使用 ExcelExampleIn.xlsxExcelExampleIn.xls 作为输入并设置隐藏未使用的行并设置从给定的最小到最大列隐藏的列。

使用 apache poi 4.1.1 进行测试和工作。

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.model.InternalSheet;
import org.apache.poi.hssf.record.DefaultRowHeightRecord;
import org.apache.poi.hssf.record.ColumnInfoRecord;
import org.apache.poi.hssf.record.RecordBase; 

import java.util.List;

public class ExcelHideUnusedRowsAndColumns {
    
 static void setUnusedRowsHidden(Sheet sheet) throws Exception {
  if (sheet instanceof XSSFSheet) {
   // in OOXML set zeroHeight property true for all undefined rows, so only rows having special settings are visible
   XSSFSheet xssfSheet = (XSSFSheet)sheet;
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet ctWorksheet = xssfSheet.getCTWorksheet();
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr ctSheetFormatPr = ctWorksheet.getSheetFormatPr();
   if (ctSheetFormatPr == null) ctSheetFormatPr = ctWorksheet.addNewSheetFormatPr();
   ctSheetFormatPr.setZeroHeight(true);
  } else if (sheet instanceof HSSFSheet) {
   // in BIFF file format set option flag 0x0002 in DEFAULTROWHEIGHT record
   HSSFSheet hssfSheet= (HSSFSheet)sheet; 
   java.lang.reflect.Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
   _sheet.setAccessible(true); 
   InternalSheet internalSheet = (InternalSheet)_sheet.get(hssfSheet);
   java.lang.reflect.Field defaultrowheight = InternalSheet.class.getDeclaredField("defaultrowheight");
   defaultrowheight.setAccessible(true); 
   DefaultRowHeightRecord defaultRowHeightRecord = (DefaultRowHeightRecord)defaultrowheight.get(internalSheet);
   defaultRowHeightRecord.setOptionFlags((short)2);
  }  
 }
 
 static void setColumnsHidden(Sheet sheet, int min, int max) throws Exception {
  if (sheet instanceof XSSFSheet) {
   // respect max column count 16384 (1 to 16384) for OOXML
   if (max > 16384) max = 16384;
   
   // in OOXML set cols settings in XML
   XSSFSheet xssfSheet = (XSSFSheet)sheet;
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet ctWorksheet = xssfSheet.getCTWorksheet();
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols ctCols = ctWorksheet.getColsArray(0);
   boolean colSettingFound = false;
   for (org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol ctCol : ctCols.getColList()) {
    if (ctCol.getMin() == min && ctCol.getMax() == max) {
     colSettingFound = true;
     ctCol.setHidden(true);
    }
    System.out.println(ctCol);  
   }
   if (!colSettingFound) {
    org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol ctCol = ctCols.addNewCol();
    ctCol.setMin(min);
    ctCol.setMax(max);
    ctCol.setHidden(true);
    System.out.println(ctCol);  
   }   
  } else if (sheet instanceof HSSFSheet) {
   // in BIFF min and max are 0-based
   min = min -1;
   max = max -1;
   // respect max column count 256 (0 to 255) for BIFF
   if (max > 255) max = 255;
   
   // in BIFF file format set hidden property in COLINFO record
   HSSFSheet hssfSheet= (HSSFSheet)sheet; 
   java.lang.reflect.Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
   _sheet.setAccessible(true); 
   InternalSheet internalSheet = (InternalSheet)_sheet.get(hssfSheet);
   java.lang.reflect.Field _records = InternalSheet.class.getDeclaredField("_records");
   _records.setAccessible(true);
   @SuppressWarnings("unchecked") 
   List<RecordBase> records = (List<RecordBase>)_records.get(internalSheet);
   boolean colInfoFound = false;
   for (RecordBase record : records) {
    if (record instanceof ColumnInfoRecord) {
     ColumnInfoRecord columnInfoRecord = (ColumnInfoRecord)record;
     if (columnInfoRecord.getFirstColumn() == min && columnInfoRecord.getLastColumn() == max) {
      colInfoFound = true;
      columnInfoRecord.setHidden(true);
     }
     System.out.println(columnInfoRecord);
    }
   }
   if (!colInfoFound) {
    ColumnInfoRecord columnInfoRecord = new ColumnInfoRecord();
    columnInfoRecord.setFirstColumn(min);
    columnInfoRecord.setLastColumn(max);
    columnInfoRecord.setHidden(true);
    records.add(records.size()-1, columnInfoRecord); 
    System.out.println(columnInfoRecord);
   }
  }
 }


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

  String inFilePath = "./ExcelExampleIn.xlsx"; String outFilePath = "./ExcelExampleOut.xlsx";

  //String inFilePath = "./ExcelExampleIn.xls"; String outFilePath = "./ExcelExampleOut.xls";

  
  try (Workbook workbook = WorkbookFactory.create(new FileInputStream(inFilePath));
       FileOutputStream out = new FileOutputStream(outFilePath ) ) {

   Sheet sheet = workbook.getSheetAt(0);
   
   //set unused rows hidden
   setUnusedRowsHidden(sheet);
   
   //set multiple columns hidden, here column 7 (G) to last column 16384 (XFD)
   setColumnsHidden(sheet, 7, 16384);

   
   workbook.write(out);
  }
 }
}