如何使用HSSF(Apache POI)在现有Excel中的两行之间插入行

ace*_*ace 52 java excel poi-hssf apache-poi

不知何故,我设法在现有的excel文件中的两行之间创建新行.问题是,一些格式化不包括行的移位.

其中之一就是隐藏的行在转换期间不是相对的.我的意思是(例如),隐藏了20到30行,但是当创建新行时,仍然存在格式化.隐藏的行也必须在插入/创建新行期间移动,它应该是21到31.

另一件事是,工作表中的另一个对象不在单元格中.在创建新行之后,文本框不会移动.它就像这些物体的位置是固定的.但我希望它移动,就像我在excel中插入新行或粘贴行一样.如果有插入新行的功能,请告诉我.

这就是我现在所拥有的,只是我代码中的一个片段.

HSSFWorkbook wb = new HSSFWorkbook(template); //template is the source of file
HSSFSheet sheet = wb.getSheet("SAMPLE");
HSSFRow newRow;
HSSFCell cellData;

int createNewRowAt = 9; //Add the new row between row 9 and 10

sheet.shiftRows(createNewRowAt, sheet.getLastRowNum(), 1, true, false);
newRow = sheet.createRow(createNewRowAt);
newRow = sheet.getRow(createNewRowAt);
Run Code Online (Sandbox Code Playgroud)

如果可以复制和粘贴行,那将是很大的帮助.但是我已经在这里问过它并且找不到解决方案.所以我决定创建一个行作为临时解决方案.我已经完成了它,但有这样的问题.

任何帮助都感激不尽.谢谢!

qwe*_*rty 68

辅助功能可以从这里无耻地复制行

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellRangeAddress;

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

public class RowCopy {

    public static void main(String[] args) throws Exception{
        HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream("c:/input.xls"));
        HSSFSheet sheet = workbook.getSheet("Sheet1");
        copyRow(workbook, sheet, 0, 1);
        FileOutputStream out = new FileOutputStream("c:/output.xls");
        workbook.write(out);
        out.close();
    }

    private static void copyRow(HSSFWorkbook workbook, HSSFSheet worksheet, int sourceRowNum, int destinationRowNum) {
        // Get the source / new row
        HSSFRow newRow = worksheet.getRow(destinationRowNum);
        HSSFRow sourceRow = worksheet.getRow(sourceRowNum);

        // If the row exist in destination, push down all rows by 1 else create a new row
        if (newRow != null) {
            worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
        } else {
            newRow = worksheet.createRow(destinationRowNum);
        }

        // Loop through source columns to add to new row
        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
            // Grab a copy of the old/new cell
            HSSFCell oldCell = sourceRow.getCell(i);
            HSSFCell newCell = newRow.createCell(i);

            // If the old cell is null jump to next cell
            if (oldCell == null) {
                newCell = null;
                continue;
            }

            // Copy style from old cell and apply to new cell
            HSSFCellStyle newCellStyle = workbook.createCellStyle();
            newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
            ;
            newCell.setCellStyle(newCellStyle);

            // If there is a cell comment, copy
            if (oldCell.getCellComment() != null) {
                newCell.setCellComment(oldCell.getCellComment());
            }

            // If there is a cell hyperlink, copy
            if (oldCell.getHyperlink() != null) {
                newCell.setHyperlink(oldCell.getHyperlink());
            }

            // Set the cell data type
            newCell.setCellType(oldCell.getCellType());

            // Set the cell data value
            switch (oldCell.getCellType()) {
                case Cell.CELL_TYPE_BLANK:
                    newCell.setCellValue(oldCell.getStringCellValue());
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    newCell.setCellValue(oldCell.getBooleanCellValue());
                    break;
                case Cell.CELL_TYPE_ERROR:
                    newCell.setCellErrorValue(oldCell.getErrorCellValue());
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    newCell.setCellFormula(oldCell.getCellFormula());
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    newCell.setCellValue(oldCell.getNumericCellValue());
                    break;
                case Cell.CELL_TYPE_STRING:
                    newCell.setCellValue(oldCell.getRichStringCellValue());
                    break;
            }
        }

        // If there are are any merged regions in the source row, copy to new row
        for (int i = 0; i < worksheet.getNumMergedRegions(); i++) {
            CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
            if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
                CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
                        (newRow.getRowNum() +
                                (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow()
                                        )),
                        cellRangeAddress.getFirstColumn(),
                        cellRangeAddress.getLastColumn());
                worksheet.addMergedRegion(newCellRangeAddress);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我已经抓住了这个代码,它对我有用.我做了两处小改动.1)使用Row,Sheet和Workbook的接口代替HSSF*具体类&2)使src行中的数据复制可选. (4认同)
  • 你知道我们如何支持修改公式,因为它们被复制了吗?我正在复制说,第1行到第2行,并希望包含公式.所以原始公式可能是第1行的总和(A1:K1),现在我希望我的第2行(副本)有总和(A2:K2).目前,它逐字复制公式,所以我得到两个使用sum(A1:K1)例如. (2认同)

小智 11

引用Qwerty的答案,您可以避免通过重复使用来增加XL大小cellStyle.而当类型是CELL_TYPE_BLANK,getStringCellValue返回""而不是null.

private static void copyRow(Sheet worksheet, int sourceRowNum, int destinationRowNum) {
  // Get the source / new row
  Row newRow = worksheet.getRow(destinationRowNum);
  Row sourceRow = worksheet.getRow(sourceRowNum);

  // If the row exist in destination, push down all rows by 1 else create a new row
  if (newRow != null) {
    worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
  } else {
    newRow = worksheet.createRow(destinationRowNum);
  }

  // Loop through source columns to add to new row
  for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
    // Grab a copy of the old/new cell
    Cell oldCell = sourceRow.getCell(i);
    Cell newCell = newRow.createCell(i);

    // If the old cell is null jump to next cell
    if (oldCell == null) {
      newCell = null;
      continue;
    }

    // Use old cell style
    newCell.setCellStyle(oldCell.getCellStyle());

    // If there is a cell comment, copy
    if (newCell.getCellComment() != null) {
      newCell.setCellComment(oldCell.getCellComment());
    }

    // If there is a cell hyperlink, copy
    if (oldCell.getHyperlink() != null) {
      newCell.setHyperlink(oldCell.getHyperlink());
    }

    // Set the cell data type
    newCell.setCellType(oldCell.getCellType());

    // Set the cell data value
    switch (oldCell.getCellType()) {
    case Cell.CELL_TYPE_BLANK:
      break;
    case Cell.CELL_TYPE_BOOLEAN:
      newCell.setCellValue(oldCell.getBooleanCellValue());
      break;
    case Cell.CELL_TYPE_ERROR:
      newCell.setCellErrorValue(oldCell.getErrorCellValue());
      break;
    case Cell.CELL_TYPE_FORMULA:
      newCell.setCellFormula(oldCell.getCellFormula());
      break;
    case Cell.CELL_TYPE_NUMERIC:
      newCell.setCellValue(oldCell.getNumericCellValue());
      break;
    case Cell.CELL_TYPE_STRING:
      newCell.setCellValue(oldCell.getRichStringCellValue());
      break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于记录,复制注释不起作用.首先,代码检查`newCell.getCellComment()`当然是`null`.但是,修复`if`不会起作用,因为注释将被移动而不是被复制.人们需要实例化一个新的"注释",这要复杂得多.请参阅http://stackoverflow.com/questions/2281221/creating-cell-comments-using-hssfclientanchor-in-apache-poi (4认同)

kri*_*hna 10

对于希望使用XSSF(Apache POI)在现有Excel中的两行之间插入行的人,已经在XSSFSheet中实现了一个方法"copyRows".

import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class App2 throws Exception{
    public static void main(String[] args){
        XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("input.xlsx"));
        XSSFSheet sheet = workbook.getSheet("Sheet1");
        sheet.copyRows(0, 2, 3, new CellCopyPolicy());
        FileOutputStream out = new FileOutputStream("output.xlsx");
        workbook.write(out);
        out.close();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

Referencing Qwerty's answer, if the destRow isnot null, sheet.shiftRows() will change the destRow's reference to the next row; so we should always create a new row:

if (destRow != null) {
  sheet.shiftRows(destination, sheet.getLastRowNum(), 1);
}
destRow = sheet.createRow(destination);
Run Code Online (Sandbox Code Playgroud)