我没有找到如何使用Apache POI API删除列 我很感激这方面的示例代码或帮助。
答案 0 :(得分:14)
Alan Williamson on the mailing list写了a small helper for column removal
package org.alanwilliamson.openbd.plugin.spreadsheet;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/*
* Helper functions to aid in the management of sheets
*/
public class SheetUtility extends Object {
/**
* Given a sheet, this method deletes a column from a sheet and moves
* all the columns to the right of it to the left one cell.
*
* Note, this method will not update any formula references.
*
* @param sheet
* @param column
*/
public static void deleteColumn( Sheet sheet, int columnToDelete ){
int maxColumn = 0;
for ( int r=0; r < sheet.getLastRowNum()+1; r++ ){
Row row = sheet.getRow( r );
// if no row exists here; then nothing to do; next!
if ( row == null )
continue;
// if the row doesn't have this many columns then we are good; next!
int lastColumn = row.getLastCellNum();
if ( lastColumn > maxColumn )
maxColumn = lastColumn;
if ( lastColumn < columnToDelete )
continue;
for ( int x=columnToDelete+1; x < lastColumn + 1; x++ ){
Cell oldCell = row.getCell(x-1);
if ( oldCell != null )
row.removeCell( oldCell );
Cell nextCell = row.getCell( x );
if ( nextCell != null ){
Cell newCell = row.createCell( x-1, nextCell.getCellType() );
cloneCell(newCell, nextCell);
}
}
}
// Adjust the column widths
for ( int c=0; c < maxColumn; c++ ){
sheet.setColumnWidth( c, sheet.getColumnWidth(c+1) );
}
}
/*
* Takes an existing Cell and merges all the styles and forumla
* into the new one
*/
private static void cloneCell( Cell cNew, Cell cOld ){
cNew.setCellComment( cOld.getCellComment() );
cNew.setCellStyle( cOld.getCellStyle() );
switch ( cNew.getCellType() ){
case Cell.CELL_TYPE_BOOLEAN:{
cNew.setCellValue( cOld.getBooleanCellValue() );
break;
}
case Cell.CELL_TYPE_NUMERIC:{
cNew.setCellValue( cOld.getNumericCellValue() );
break;
}
case Cell.CELL_TYPE_STRING:{
cNew.setCellValue( cOld.getStringCellValue() );
break;
}
case Cell.CELL_TYPE_ERROR:{
cNew.setCellValue( cOld.getErrorCellValue() );
break;
}
case Cell.CELL_TYPE_FORMULA:{
cNew.setCellFormula( cOld.getCellFormula() );
break;
}
}
}
}
答案 1 :(得分:4)
cporte的回答非常好,但有点难以阅读。
对于每一行,删除表示要删除的列的单元格,并将所有单元格移动到该列左侧的所有单元格。
//Variables for completeness
Sheet sheet;
int columnToDelete;
for (int rId = 0; rId <= sheet.getLastRowNum(); rId++) {
Row row = sheet.getRow(rId);
for (int cID = columnToDelete; cID < row.getLastCellNum(); cID++) {
Cell cOld = row.getCell(cID);
if (cOld != null) {
row.removeCell(cOld);
}
Cell cNext = row.getCell(cID + 1);
if (cNext != null) {
Cell cNew = row.createCell(cID, cNext.getCellType());
cloneCell(cNext, cNew);
sheet.setColumnWidth(cID, sheet.getColumnWidth(cID + 1));
}
}
}
<小时/> 克隆单元格方法从另一个答案复制完整性:
private static void cloneCell( Cell cNew, Cell cOld ){
cNew.setCellComment( cOld.getCellComment() );
cNew.setCellStyle( cOld.getCellStyle() );
switch ( cNew.getCellType() ){
case Cell.CELL_TYPE_BOOLEAN:{
cNew.setCellValue( cOld.getBooleanCellValue() );
break;
}
case Cell.CELL_TYPE_NUMERIC:{
cNew.setCellValue( cOld.getNumericCellValue() );
break;
}
case Cell.CELL_TYPE_STRING:{
cNew.setCellValue( cOld.getStringCellValue() );
break;
}
case Cell.CELL_TYPE_ERROR:{
cNew.setCellValue( cOld.getErrorCellValue() );
break;
}
case Cell.CELL_TYPE_FORMULA:{
cNew.setCellFormula( cOld.getCellFormula() );
break;
}
}
}
答案 2 :(得分:2)
codewing的解决方案对我有用,就像一个带有以下微小变化的魅力:
完整代码如下(为清晰起见):
private void deleteColumn(Sheet sheet, int columnToDelete) {
for (int rId = 0; rId < sheet.getLastRowNum(); rId++) {
Row row = sheet.getRow(rId);
for (int cID = columnToDelete; cID < row.getLastCellNum(); cID++) {
Cell cOld = row.getCell(cID);
if (cOld != null) {
row.removeCell(cOld);
}
Cell cNext = row.getCell(cID + 1);
if (cNext != null) {
Cell cNew = row.createCell(cID, cNext.getCellTypeEnum());
cloneCell(cNew, cNext);
//Set the column width only on the first row.
//Other wise the second row will overwrite the original column width set previously.
if(rId == 0) {
sheet.setColumnWidth(cID, sheet.getColumnWidth(cID + 1));
}
}
}
}
}
private void cloneCell(Cell cNew, Cell cOld) {
cNew.setCellComment(cOld.getCellComment());
cNew.setCellStyle(cOld.getCellStyle());
if (CellType.BOOLEAN == cNew.getCellTypeEnum()) {
cNew.setCellValue(cOld.getBooleanCellValue());
} else if (CellType.NUMERIC == cNew.getCellTypeEnum()) {
cNew.setCellValue(cOld.getNumericCellValue());
} else if (CellType.STRING == cNew.getCellTypeEnum()) {
cNew.setCellValue(cOld.getStringCellValue());
} else if (CellType.ERROR == cNew.getCellTypeEnum()) {
cNew.setCellValue(cOld.getErrorCellValue());
} else if (CellType.FORMULA == cNew.getCellTypeEnum()) {
cNew.setCellValue(cOld.getCellFormula());
}
}
答案 3 :(得分:1)
有一个术语混淆:作者作者希望实现的操作称为Apache POI接口的列移动术语。 org.apache.poi.ss.usermodel.Sheet
界面提供了一种执行此类操作的干净方法:
sheet.shiftColumns(startRangeIndex, endRangeIndex, directionQuantifier);
例如,通过调用以下命令即可轻松实现将B列向左移动一个位置:
Sheet sheet = loadRequiredSheet();
sheet.shiftColumns(2, 3, -1);
Column A Column B Column C
Data here to be removed <- t should be moved to the left
答案 4 :(得分:0)
我认为您必须关闭每个HSSFRow并调用HSSFRow.getCell然后调用HSSFRow.removeCell。 API面向行而不是列,并且很少有操作在整个列级别工作。
示例代码(未经测试):
HSSFSheet sheet = ...
int colToRemove = 5;
Iterator rowIter = sheet.iterator();
while (rowIter.hasNext()) {
HSSFRow row = (HSSFRow)rowIter.next();
HSSFCell cell = row.getCell(colToRemove);
row.removeCell(cell);
}