2017-09-13 1453 views
0

到目前为止,我使用Spring MVC进行了低层次编码。如何使用java + poi在excel中设置单元格背景颜色

重要的 - 我不使用这里HSSFWorkbook

那么什么是POI方法setCellStyle的StreamingReader相当于如果单元格的数据进行格式化以及例如

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

你想要处理的文件有多大? – JensS

+0

@RajuSharma不,我没有得到任何错误..我不知道如何在上面的代码上应用单元格背景颜色。 –

回答

0

这里的一个局部解决方案,它可以帮助你:

  1. 我已经设置RowCacheSize的1000(与更高的价值,它的方式花了太长时间)

  2. 我创建了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); 
    } 
+0

让我知道这是否有帮助。 – JensS

+0

感谢您的帮助..但是,当我这样做时,我得到了'java.io.IOException:流关闭' –

+0

它开始计数行,还是从头开始关闭流? – JensS

0

Excel Streaming Reader被命名为读者,因为它仅用于阅读。有一个StreamingWorkbook它实现工作簿,但它的大部分方法尚未实现。所以这是一个到现在为止的草案。

如果涉及到巨大的Excel文件,那么我们必须考虑一个完全不同的方法,而不是从这些巨大的文件中创建HSSFWorkbookXSSFWorkbook

A 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_FOREGR‌​OUND) { 
     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_FOREGR‌​OUND); 
     } 

     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(); 
    } 
} 
} 
相关问题