我有此代码,并且此错误不断出现。我只有一个excel,但是似乎没有任何作用,我已经尝试了很多在网上冲浪的选项,但是根据我想做的事情似乎没有任何作用。
我使用不同的情况来简化我的业务逻辑,并且我不会更改它,所以我不确定如何解决此问题。
private static final String nombreArchivo = "casoPrueba.xlsx";
private static final String rutaArchivo = "src\\test\\resources\\data\\" + nombreArchivo;
public static XSSFSheet SacaHojaSegunTipo(String tipo) throws IOException {
FileInputStream fis = new FileInputStream(new File(rutaArchivo));
workbook = new XSSFWorkbook(fis);
XSSFSheet spreadsheet = workbook.getSheetAt(0);
if (tipo .equals("Candidatos Minorista")) {
spreadsheet = workbook.getSheetAt(1);
}else if(tipo.equals("Conversion Candidatos")){
spreadsheet = workbook.getSheetAt(2);
}else if(tipo.equals("Cuentas")){
spreadsheet = workbook.getSheetAt(3);
}else if(tipo.equals("Detalle Cuenta")){
spreadsheet = workbook.getSheetAt(4);
}else if(tipo.equals("Historial de Cuentas")){
spreadsheet = workbook.getSheetAt(5);
}else if(tipo.equals("Navegar Cuentas")){
spreadsheet = workbook.getSheetAt(6);
}else if(tipo.equals("Validar Número Operación")){
spreadsheet = workbook.getSheetAt(7);
}else if(tipo.equals("Validar Tipos de Productos")){
spreadsheet = workbook.getSheetAt(8);
}else if(tipo.equals("Validar Referencia y Cód. Auto.")){
spreadsheet = workbook.getSheetAt(9);
}
return spreadsheet;
}
答案 0 :(得分:0)
这样的事情(我试图尽可能少地更改您的代码,所以它并不完美)
private static final String nombreArchivo = "casoPrueba.xlsx";
private static final String rutaArchivo = "src\\test\\resources\\data\\" + nombreArchivo;
private static XSSFWorkbook workbook = null;
public static XSSFSheet SacaHojaSegunTipo(String tipo) throws IOException {
if (workbook == null) {
try (FileInputStream fis = new FileInputStream(new File(rutaArchivo))) {
workbook = new XSSFWorkbook(fis);
}
}
XSSFSheet spreadsheet = null;
switch (tipo) {
case "Candidatos Minorista":
spreadsheet = workbook.getSheetAt(1);
break;
case "Conversion Candidatos":
spreadsheet = workbook.getSheetAt(2);
break;
case "Cuentas":
spreadsheet = workbook.getSheetAt(3);
break;
case "Detalle Cuenta":
spreadsheet = workbook.getSheetAt(4);
break;
case "Historial de Cuentas":
spreadsheet = workbook.getSheetAt(5);
break;
case "Navegar Cuentas":
spreadsheet = workbook.getSheetAt(6);
break;
case "Validar Número Operación":
spreadsheet = workbook.getSheetAt(7);
break;
case "Validar Tipos de Productos":
spreadsheet = workbook.getSheetAt(8);
break;
case "Validar Referencia y Cód. Auto.":
spreadsheet = workbook.getSheetAt(9);
break;
default:
spreadsheet = workbook.getSheetAt(0);
}
return spreadsheet;
}
答案 1 :(得分:0)
首先,请简短一点:值得注意以下内容
https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFWorkbook.html#XSSFWorkbook-java.io.InputStream-
使用InputStream比使用File需要更多的内存,因此如果 文件可用,那么您应该做类似的事情
OPCPackage pkg = OPCPackage.open(path); XSSFWorkbook wb = new XSSFWorkbook(pkg); // work with the wb object ...... pkg.close(); // gracefully closes the underlying zip file
(尽管执行wb.close()
也会关闭文件和流)。
现在,您的核心问题是,在不再需要工作表或工作簿之后,您需要释放资源,但是由于这些资源隐藏在方法内部,因此您目前无法这样做。
因此,完成操作后,您需要授予呼叫者访问权以将其关闭。这是一个优先事项,但是我个人更希望将电子表格封装到其自己的类中-毕竟,电子表格本身就是一个明确定义的对象!因此,这需要从static
进行更改,所以类似:
public class RutaArchivo implements AutoCloseable {
private static final String nombreArchivo = "casoPrueba.xlsx";
private static final String rutaArchivo = "src\\test\\resources\\data\\" + nombreArchivo;
public static final String CANDIDATOS_MINORISTA = "Candidatos Minorista";
public static final String CONVERSION_CANDIDATOS = "Conversion Candidatos"
public static final String CUENTAS = "Cuentas";
private XSSFWorkbook workbook;
public RutaArchivo() throws InvalidFormatException, IOException {
workbook = new XSSFWorkbook(new File(rutaArchivo));
}
@Override
public void close() throws Exception {
if (workbook != null) {
workbook.close();
workbook = null;
}
}
public XSSFSheet sacaHojaSegunTipo(String tipo) {
if (workbook == null) {
throw new IllegalStateException("It's closed");
}
XSSFSheet spreadsheet = workbook.getSheetAt(0);
if (tipo .equals(CANDIDATOS_MINORISTA)) {
spreadsheet = workbook.getSheetAt(1);
}else if(tipo.equals(CONVERSION_CANDIDATOS)){
spreadsheet = workbook.getSheetAt(2);
}else if(tipo.equals(CUENTAS)){
spreadsheet = workbook.getSheetAt(3);
// etc, etc
}
return spreadsheet;
}
}
需要注意的几件事:
如果我们希望调用者关闭文件,则应该明确让他们也采取一些措施来打开文件,否则,将其挂起很容易。在上面的示例中,这在创建对象时是隐式的-就像FileInputStream等标准Java类型一样。
使RutaArchivo
成为AutoCloseable意味着它可以在try-with-resources中使用,因此会自动关闭-例如:
try (RutaArchivo rutaArchivo = new RutaArchivo()) {
XSSFSheet cuentas = rutaArchivo.getSheet(RutaArchivo.CUENTAS);
}
在工作表名称中使用常量可以减少错误(例如,调用该方法时没有错别字)
因为这是它自己的类,而不是static
方法,所以编写单元测试时更容易替换或模拟。
无论如何,有一些想法-希望他们有所帮助。