到目前为止,我使用Spring MVC进行了编码。
重要 - 我没有在这里使用HSSFWorkbook
那么StreamingReader中POI方法setCellStyle的等价物是什么
InputStream is = new FileInputStream(new File("file path"));
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(90000000)
.bufferSize(4096)
.sheetIndex(0)
.read(is);
for (Row r : reader) {
Test_huge_excel_data data = new Test_huge_excel_data();
data.setCol1(r.getCell(0).getStringCellValue());
data.setCol2(r.getCell(1).getStringCellValue());
drtamminaService.saveExcelData(data);
}
我的要求是假设单元格数据格式不正确,例如“错误的数据格式”,所以我想更改特定的单元格背景颜色。
但如果我正在使用它能够做到这一点
XSSFWorkbook myWorkBook = new XSSFWorkbook (fileInputStream);
XSSFCellStyle style = myWorkBook.createCellStyle();
style.setFillForegroundColor(IndexedColors.RED.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
row.getCell(30).setCellStyle(style);
但是当我使用这段代码时,我无法加载大量文件。
在上面的代码中,我只需要更改以添加样式。
答案 0 :(得分:0)
以下是可能对您有所帮助的部分解决方案:
我已将rowCacheSize设置为1000(使用更高的值,花费的时间太长)
我自己创建了cellStyle并在其上使用了setCellStyle。
我有 - 但是到目前为止还没能找到保存方法,所以我无法测试它。
StreamingReader reader = StreamingReader
.builder()
.rowCacheSize(1000)
.bufferSize(4096)
.sheetIndex(0)
.read(is);
XSSFCellStyle style = new XSSFCellStyle(new StylesTable());
style.setFillForegroundColor(IndexedColors.RED.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
for (Row row : reader) {
System.out.println(row.getRowNum());
row.getCell(3).setCellStyle(style);
}
答案 1 :(得分:0)
Excel Streaming Reader名为读者,因为它仅供阅读使用。有一个StreamingWorkbook实现了Workbook,但大部分方法尚未实现。所以这是一个草案,直到现在。
如果涉及巨大的Excel
文件,那么我们必须考虑一种完全不同的方法,而不是从这些大文件中创建HSSFWorkbook
或XSSFWorkbook
。
Workbook
只能作为一个整体创建。但是我们当然可以将Excel
文件的单个部分(如工作表部分(包含行和单元格))或样式部分(包含单元格样式,字体,填充,边框等)或共享字符串部分(包含单元格的文本内容)并解析它们。这导致较少的资源消耗,因为单个部分不如整个文件大。但它还需要更多关于文件内部结构的知识。最简单的任务是读取和解析单个部分,但如果涉及到变化,那么需要将它们写入部分流,那么它会变得很复杂,因为我们还需要了解并考虑部分关系
幸运的是XSSF
(*.xlsx
)部分是XML
,因此要解析(读取)并使用StAX进行写入。
以下代码使用此方法。它获取样式表部分,sheet1部分形成*.xlsx
文件的ZIP包,然后在此文件的Sheet1的每第5行的每个单元格中设置红色背景颜色。此外,如果文件可能很大,那么代码应该以尽可能少的资源量运行。
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.XMLEvent;
import javax.xml.namespace.QName;
import java.io.File;
import java.io.OutputStream;
import java.util.regex.Pattern;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
class StaxReadAndWriteTestRowBGColor {
public static void main(String[] args) {
try {
File file = new File("file.xlsx");
OPCPackage opcpackage = OPCPackage.open(file);
//get the styles table
PackagePart stylestabletablepart = opcpackage.getPartsByName(Pattern.compile("/xl/styles.xml")).get(0);
StylesTable stylestable = new StylesTable(stylestabletablepart);
//get the sheet1 package part
PackagePart sheetpart = opcpackage.getPartsByName(Pattern.compile("/xl/worksheets/sheet1.xml")).get(0);
//create reader and writer for the sheet1 package part
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(sheetpart.getInputStream());
XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(sheetpart.getOutputStream());
//create a factory for producing XML elements and attributes
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
int rowsCount = 0;
Map<Integer, Integer> styleIdxMap = new HashMap<>(); //a Map for mapping old styleIdx to new styleIdx
while(reader.hasNext()){ //loop over all XML in sheet1.xml
XMLEvent event = (XMLEvent)reader.next();
if(event.isStartElement()){
StartElement startElement = (StartElement)event;
QName startElementName = startElement.getName();
if(startElementName.getLocalPart().equalsIgnoreCase("row")) { //start element of row
rowsCount++;
} else if (startElementName.getLocalPart().equalsIgnoreCase("c")) { //start element of cell
if (rowsCount % 5 == 0) { // every 5th row
Attribute attribute;
Iterator attributeIterator = startElement.getAttributes(); //get cell's attributes
List<Attribute> attributeList = new ArrayList<>();
int styleIdx = 0;
while (attributeIterator.hasNext()) {
attribute = (Attribute)attributeIterator.next();
if ("s".equals(attribute.getName().getLocalPart())) { //cell has style attribute already
styleIdx = Integer.valueOf(attribute.getValue()); //so get the styleIdx
//but don't put in the attributeList since we wants creating it new
} else {
attributeList.add(attribute);
}
}
XSSFCellStyle cellstyle;
cellstyle = stylestable.getStyleAt(styleIdx);
if (cellstyle.getFillForegroundColor() != IndexedColors.RED.getIndex()
&& cellstyle.getFillPatternEnum() != FillPatternType.SOLID_FOREGROUND) {
if (styleIdxMap.get(styleIdx) == null) { //old cell style is not mapped until now
cellstyle = (XSSFCellStyle)cellstyle.clone(); //so clone style
styleIdxMap.put(styleIdx, (int)cellstyle.getIndex()); //and put in the map
} else {
cellstyle = stylestable.getStyleAt(styleIdxMap.get(styleIdx)); //else get from already mapped style
}
cellstyle.setFillForegroundColor(IndexedColors.RED.getIndex());
cellstyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
styleIdx = (int)cellstyle.getIndex(); //get final styleIdx
attribute = eventFactory.createAttribute("s", Integer.toString(styleIdx)); //create new style attribute
attributeList.add(attribute); //add it to the attributeList now
StartElement newstartElement = eventFactory.createStartElement(startElementName,
attributeList.iterator(),
startElement.getNamespaces());
event = newstartElement; //create a new event for the writer using the new cell StartElement
}
}
}
writer.add(event); //by default write each read event
}
writer.flush();
//write out the styles table
OutputStream out = stylestabletablepart.getOutputStream();
stylestable.writeTo(out);
out.close();
opcpackage.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}