【发布时间】:2016-05-06 07:22:07
【问题描述】:
所以我正在尝试编写一个程序来扫描 Excel 文件的一行中的特定模式。即 N 后跟任意字母,然后是 S 或 T(每个字母占据一个单元格)。
问题是,我使用的 excel 文件非常庞大,大约有 3000 行和近 1000 列。我试图仅在前 60 行中搜索此模式,以减少 Java 堆空间。我怎样才能适合我的算法来做到这一点?我仍然遇到内存不足异常。
我的代码如下:
import java.awt.List;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelReader {
public int Reader(File file) throws IOException, EncryptedDocumentException, InvalidFormatException {
FileInputStream fis = new FileInputStream(file);
String filepath = file.getPath();
Workbook wb = WorkbookFactory.create(new File(filepath));
XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
ArrayList<Integer> list = new ArrayList<Integer>();
int rows;
int cols = 0;
int temp = 0;
rows = sheet.getPhysicalNumberOfRows();
for (int i = 0; i < 10 || i < 60; i++) {
row = sheet.getRow(i);
if (row != null) {
temp = sheet.getRow(i).getPhysicalNumberOfCells();
if (temp > cols)
cols = temp;
}
}
for (int r = 0; r <= 60; r++) {
row = sheet.getRow(r);
if (row != null) {
for (int c = 0; c <= cols; c++) {
int numblanks = 0;
cell = row.getCell((short) c);
if (cell != null) {
//System.out.print(cell + "\t\t");
} else {
//System.out.print("\t\t");
}
if (cell != null && cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
if ("N".equals(cell.getStringCellValue())) {
for (int k = c; k <= cols; k++) {
if ("-".equals(row.getCell(k).getStringCellValue())) {
numblanks++;
continue;
}
if ("S".equals(row.getCell(c + 2 + numblanks).getStringCellValue())
|| "T".equals(row.getCell(c + 2 + numblanks).getStringCellValue())) {
list.add((int) sheet.getRow(1).getCell(c).getNumericCellValue());
break;
}
}
}
}
}
System.out.println();
}
}
System.out.println();
System.out.println("Rows: " + rows);
System.out.println("Columns: " + cols);
System.out.println(list);
return temp;
}
}
【问题讨论】:
-
能不能不把它转换成CSV然后随便从文件中读取n个字节?
-
在 VBA 中,您可以使用
ExecuteExcel4Macro("'" & path & "[" & file & "]" & sheet & "'!" & range)获取值而无需打开文件...但我怀疑 java 中有类似的东西...但也许您可以使用一些转换或创建一个“ autorun"-workbook 使用它为原始文件的一部分创建副本...只是一个想法。 -
哪一行给你带来了问题???你的意思是这样做 10 次还是 60 次 :: (int i = 0; i
-
也许 find 方法可以帮到你docs.microsoft.com/en-us/office/vba/api/excel.range.find
-
我不知道你是否意识到这一点,但 *.xlsx 文件实际上是一个压缩的 XML 结构,但它很难理解。如果您设法了解其工作原理,您可能会针对该结构发起一些
XPath查询,从而更轻松地获取信息。
标签: java excel error-handling