我有一个很大的xlsx文件,其中有一个空的“数据源表”和其他包含大量使用数据源表的公式的表。我的应用程序应该生成数据,打开文件,用数据填充空白表并保存。我正在尝试使用Apache
POI来完成所有这些工作。问题是打开文件占用了无法接受的内存和时间。我读过其他主题,找不到解决方案。这是我打开文件的方式:
pkg = OPCPackage.open(filename);
wb = new XSSFWorkbook(pkg);
请注意,使用SXSSFWorkbook
不起作用,因为它的构造函数采用了XSSFWorkbook
我首先无法创建的构造函数。我只需要在文件中填充一张空白纸,而无需将其完全加载到内存中。有任何想法吗??
谢谢!!
您可以尝试仅使用OPCPackage
而不创建Workbook
。但是,我们必须在较低级别的org.openxmlformats.schemas.spreadsheetml.x2006.main
对象上工作。这意味着XSSF
在将字符串值存储为数据(SharedStringsTable
)和评估公式时,我们没有对象的支持。
该示例使用一个Excel
至少包含4个工作表的工作簿。第三个工作表是您的“数据源表”。它必须存在并且将被新数据覆盖。第四个工作表是其中公式引用“数据源表”的工作表。由于我们不能使用评估器,因此必须将FullCalcOnLoad设置为true。如果我们不这样做,则必须按[Ctrl]
+ [Alt] + [Shift] + [F9]强制完全重新计算。
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.model.SharedStringsTable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlException;
import javax.xml.namespace.QName;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Pattern;
class ReadAndWriteTest5 {
public static void main(String[] args) {
try {
File file = new File("ReGesamt11_3Test.xlsx");
//we only open the OPCPackage, we don't create a Workbook
OPCPackage opcpackage = OPCPackage.open(file);
//if there are strings in the SheetData, we need the SharedStringsTable
PackagePart sharedstringstablepart = opcpackage.getPartsByName(Pattern.compile("/xl/sharedStrings.xml")).get(0);
SharedStringsTable sharedstringstable = new SharedStringsTable();
sharedstringstable.readFrom(sharedstringstablepart.getInputStream());
//create empty WorksheetDocument for the "data source sheet"
WorksheetDocument worksheetdocument = WorksheetDocument.Factory.newInstance();
CTWorksheet worksheet = worksheetdocument.addNewWorksheet();
CTSheetData sheetdata = worksheet.addNewSheetData();
//put some data in for the "data source sheet"
for (int i = 0; i < 10; i++) {
CTCell ctcell= sheetdata.addNewRow().addNewC();
CTRst ctstr = CTRst.Factory.newInstance();
ctstr.setT("DataRow " + i);
int sRef = sharedstringstable.addEntry(ctstr);
ctcell.setT(STCellType.S);
ctcell.setV(Integer.toString(sRef));
ctcell=sheetdata.getRowArray(i).addNewC();
ctcell.setV(""+(i*100+(i+1)*10+(i+2))+"."+((i+3)*10+(i+4)));
}
//write the SharedStringsTable
OutputStream out = sharedstringstablepart.getOutputStream();
sharedstringstable.writeTo(out);
out.close();
//create XmlOptions for saving the worksheet
XmlOptions xmlOptions = new XmlOptions();
xmlOptions.setSaveOuter();
xmlOptions.setUseDefaultNamespace();
xmlOptions.setSaveAggressiveNamespaces();
xmlOptions.setCharacterEncoding("UTF-8");
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet"));
Map<String, String> map = new HashMap<String, String>();
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
xmlOptions.setSaveSuggestedPrefixes(map);
//get the PackagePart of the third sheet which is the "data source sheet"
//this sheet must exist and will be replaced with the new content
PackagePart sheetpart = opcpackage.getPartsByName(Pattern.compile("/xl/worksheets/sheet3.xml")).get(0);
//save the worksheet as the third sheet which is the "data source sheet"
out = sheetpart.getOutputStream();
worksheet.save(out, xmlOptions);
out.close();
//get the PackagePart of the fourth sheet which is the sheet on which formulas are referencing the "data source sheet"
//since we can't use Evaluator, we must force recalculation on load for this sheet
sheetpart = opcpackage.getPartsByName(Pattern.compile("/xl/worksheets/sheet4.xml")).get(0);
worksheetdocument = WorksheetDocument.Factory.parse(sheetpart.getInputStream());
worksheet = worksheetdocument.getWorksheet();
//setFullCalcOnLoad true
if (worksheet.getSheetCalcPr() == null) {
worksheet.addNewSheetCalcPr().setFullCalcOnLoad(true);
} else {
worksheet.getSheetCalcPr().setFullCalcOnLoad(true);
}
out = sheetpart.getOutputStream();
worksheet.save(out, xmlOptions);
out.close();
opcpackage.close();
} catch (InvalidFormatException ifex) {
ifex.printStackTrace();
} catch (FileNotFoundException fnfex) {
fnfex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
} catch (XmlException xmlex) {
xmlex.printStackTrace();
}
}
}
我是编程界的新手。嗯,我正在尝试使用ApachePOI库读取excel文件(5行5列)。我实际上有两个相同问题的实现。在第一个代码片段中,我只是读取excel文件并将其打印到控制台中。 然而,现在我正试图将读取的excel数据保存到一个数组中。所以我想在动态获取excel行和列大小后设置数组大小。但令我惊讶的是,当我执行第二个代码段时,似乎“while(cellIterator.hasNext()
问题内容: 如何控制转盘中包含哪些文件?似乎没有被使用。 更新 : 我错了从源tarball安装与安装轮子之间的区别。源代码发行版包含中指定的文件,但已安装的软件包仅包含python文件。无论是通过源分发版,egg还是wheel安装,都需要采取步骤来确定应安装的其他文件。即,其他软件包文件需要package_data,而软件包外部文件(例如命令行脚本或系统配置文件)需要data_files。 原始
这是我的配置类。 这是我的出版商课 我正在犯错误。 2020-10-04 14:28:24.628错误17008 --- [ 127.0.0.1:5672]o. s. a. r. c.CachingConnectionFactory:通道关闭:通道错误;协议方法:#方法
我正在处理一个大的excel文件(大于40MB,超过100k行和50列)。我正在使用POI(3.10.1版本)事件流成功地读取它,然后进行一些计算并将结果存储到列表中。 现在我必须将这个列表作为一列附加到同一个文件中。在这一部分中,我面临着一个问题。 我试图通过使用以下代码来实现这一点 它可以很好地处理较小的文件,但问题是我对于较大的文件内存不足。现在我尝试修改它并使用SXSSF代替XSFF来解决
问题内容: 我想对iText执行以下操作: (1)解析现有的PDF文件 (2)在文档的现有单页上添加一些数据(例如时间戳) (3)写出文件 我似乎无法弄清楚如何使用iText做到这一点。用伪代码可以做到这一点: Document document = reader.read(input); document.add(new Paragraph(“my timestamp”)); writer.wr
问题内容: 假设我有一些要将JavaScript操作添加到的链接: 当页面加载时,我给他们所有的click事件: 但让我们说之后,我添加了另一个元素,但我想给它相同的事件。我不能这样做: 因为前三个事件将包含两个事件。处理此问题的最佳方法是什么? 问题答案: 您可以将$ .on绑定到这样的dom中始终存在的父元素。 请注意: 您可以用dom中将始终存在的元素的任何父级替换,并且父级越近越好。 具有