用Apache-POI编写工作簿后出现问题

时间:2017-01-21 03:48:47

标签: java excel apache-poi

将数据插入带有.xlsm扩展名的Excel模板的工作表后,我遇到了问题。代码有效。它正确地复制了有问题的数据,但是当我尝试运行一个特定的宏时,它会获取导入的数据,它不会识别所有行,只识别前两行。

但是,如果我复制并粘贴第二列中的任何单元格,例如如果我在B2中复制B2并执行宏,它会识别插入行的总数。你能帮助我吗?我希望我很清楚。

这是我的功能代码

public String generarExcelSalida(String codCampaña,JDateChooser fechaParametro,String tfOutFolder){
String fileName="Modelo Caida "+codCampaña+".xlsm";
String exitFilePath=tfOutFolder+"\\"+fileName;
FileInputStream fileIn=null;
FileOutputStream fileOut=null;
SimpleDateFormat dParam=new SimpleDateFormat("dd/MM/yyyy");
String dateParam = dParam.format(fechaParametro.getDate()).toString();
ResultSet rs=DBManager.ConsultaCaida(dateParam, codCampaña);
try {
    // Here I'm opening my template file
    fileIn=new FileInputStream(FileManagement.carpetaTemplate+"\\Template_Caidas.xlsm");

    XSSFWorkbook workbook=new XSSFWorkbook(OPCPackage.open(fileIn));
    XSSFSheet sheet9=workbook.getSheet("BASE_DATOS");

    int i=1; // This parameter is used to getRow(i)
    while(rs.next()){
        XSSFRow row = sheet9.getRow(i);

        XSSFCell cell1=row.getCell(0);
        XSSFCell cell2=row.getCell(1);
        XSSFCell cell3=row.getCell(2);
        XSSFCell cell4=row.getCell(3);
        XSSFCell cell5=row.getCell(4);
        XSSFCell cell6=row.getCell(5);
        //Writing de ResultSet values on Sheet "BASE_DATOS"
        cell1.setCellValue(rs.getString("Producto Comercial"));
        cell2.setCellValue(rs.getInt("Nro Certificados"));
        cell3.setCellValue(rs.getString("DefEstado"));
        cell4.setCellValue(rs.getDate("Año-Mes Venta"));
        cell5.setCellValue(rs.getDate("Año-Mes Inicio Vigencia"));
        cell6.setCellValue(rs.getDate("AM Estado"));
        i++;// next Sheet.row

        }

    fileOut=new FileOutputStream(exitFilePath);
    //writing the workbook in a new file, it is like SAVE AS
    workbook.write(fileOut);
    if(fileOut!=null) fileOut.close();
    if(fileIn!=null) fileIn.close();
} catch (IOException | InvalidFormatException | SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
//return the path of the new file
return exitFilePath;
}

这是宏的代码

Private Sub Base_Datos()
Dim Numero_Registro As Integer
Dim Celda As Range
Dim Columna, Fila As Integer

Sheets("BASE_DATOS").Select

' Busqueda del limite de Filas
Fila = Range("Numero_Registro") + 1

' Busqueda del limite de Columnas
Set Celda = Range("1:1").Find("BAJAS")
Columna = Celda.Column

With Range("a1")
' Copiar Pegar
Range(.Cells(2, Columna), .Cells(2, 100)).Select
Selection.Copy

Range(.Cells(3, Columna), .Cells(Fila, 100)).Select
Selection.PasteSpecial Paste:=xlFormulas

End With
End Sub

1 个答案:

答案 0 :(得分:1)

因此,根据您的评论,问题是需要重新计算,因为宏依赖于使用COUNTA来计算已填充单元格的单元格值。

两种可能的解决方案:

首先:在保存工作簿之前,您可以使用FormulaEvaluator来评估apache poi中的公式:

...
    //writing the workbook in a new file, it is like SAVE AS
    XSSFFormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
    evaluator.evaluateAll();
    workbook.write(fileOut);
...

这可能会失败,具体取决于公式的种类。

如果使用evaluateAll()失败,您至少可以使用COUNTA公式评估单元格。这不应该失败,因为apache poi支持COUNTA函数。

阅读Formula Evaluation了解具体操作方法。

第二:您可以强制Excel在打开文件时进行重新计算:

...
    //writing the workbook in a new file, it is like SAVE AS
    workbook.setForceFormulaRecalculation(true);
    workbook.write(fileOut);
...

打开文件时可能会导致长时间的处理。