2017-09-13 1452 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(); 
    } 
} 
} 
相關問題