2012-10-17 201 views
1

我想知道是否有方法使用Apache POI(XSSF)調整圖表大小。目前,我正在使用Excel模板,當使用namedRanges插入更多數據時,該模板的圖表會發生變化。如何使用XSSF(Apache POI 3.8)調整圖表大小?

一切正常,我現在面臨的唯一的麻煩是:

  • 圖表始終保持相同的大小,因此,如果有更多的條目,它就會混亂使圖表那種無用的。
  • 我正在使用日期,但我無法將日期表示爲圖表上的日/月(17/10)。基本上,而不是2001年4月1日,將其寫入36982.

工作簿的目的是列出幾項工作,並檢查他們是否在給定日期需要較長的時間,該圖是用於幫助識別的ocurrences更長的時間。作業運行時間可能從幾秒到幾小時不等。

這是代碼我使用:

package le_package.poi_tests.xssflibrary; 

import java.io.*; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import org.apache.poi.openxml4j.opc.OPCPackage; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.Name; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 
import org.apache.poi.xssf.usermodel.XSSFWorkbook; 

public class POIReadFile { 
    public static void main(String[] args) { 
     try 
     {   
      String jobName = "I am a job"; 
      String jobParent = "I am your father, Job.";   
      int rowNum = 40; 
      int deface = 4; 

      //Open Excel as OOXML 
      XSSFWorkbook currentWorkbook = new XSSFWorkbook(OPCPackage.open("include/excelTemplate.xlsx")); 

      //Get sheet in position 0 
      Sheet currentSheet = currentWorkbook.getSheetAt(0); 

      //Get sheet name for processing 
      String sheetName = currentSheet.getSheetName(); 

      //Set values for headers 
      currentSheet.getRow(1).getCell(0).setCellValue(jobName);    
      currentSheet.getRow(1).getCell(1).setCellValue(jobParent);    

      for (int i=0; i<rowNum; i++) 
      { 
       //Create row in a given position 
       Row newRow = currentSheet.createRow(i+deface); 

       //Create cell within row 
       Cell newCell0 = newRow.createCell(0); 
       Cell newCell1 = newRow.createCell(1); 
       Cell newCell2 = newRow.createCell(2); 
       String cellDate = ""; 

       /* Set CellType 
       * 0 - Numeric | 1 - String | 2 - Formula | 3 - Blank | 4 - Boolean | 5 - Error */ 
       newCell0.setCellType(0); 
       cellDate = "3/"+(i+1)+"/2001 00:00:00"; 

       //Convert text into date 
       Date currentCellDate = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(cellDate); 
       //System.out.println(currentCellDate.toString()+"--"+cellDate); 

       //Set CellValue 
       newCell0.setCellValue(currentCellDate); 


       cellDate = "4/"+(i+1)+"/2001 00:00:00"; 
       currentCellDate = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(cellDate); 
       //System.out.println(currentCellDate.toString()+"--"+cellDate);    
       newCell1.setCellType(0); 
       newCell1.setCellValue(currentCellDate); 

       //setCellFormula sets the formula to be evaluated by excel, it doesn't need to start with '=' 
       newCell2.setCellFormula("A" + (i+deface+1) + "-B" + (i+deface+1));    
      }   

      //Search for named range 
      Name rangeCell = currentWorkbook.getName("startRange");   
      //Set new range for named range 
      String reference = sheetName + "!$A$" + (deface+1) + ":$A$" + (rowNum+deface);   
      //Assigns range value to named range 
      rangeCell.setRefersToFormula(reference); 

      rangeCell = currentWorkbook.getName("endRange");    
      reference = sheetName + "!$B$"+(deface+1) + ":$B$" + (rowNum+deface); 
      rangeCell.setRefersToFormula(reference);    

      rangeCell = currentWorkbook.getName("elapsedTime"); 
      reference = sheetName + "!$C$"+(deface+1) + ":$C$" + (rowNum+deface); 
      rangeCell.setRefersToFormula(reference); 

      //Create a fileStream to write into a file 
      FileOutputStream newExcelFile = new FileOutputStream(jobName+".xlsx"); 

      //Write Stream 
      currentWorkbook.write(newExcelFile); 

      //Close New Excel File 
      newExcelFile.close();   
     } 
     catch (Exception e) 
     { 
      System.out.println("AAAAARGH, I was wounded by the following exception!:"); 
      e.printStackTrace(); 
      System.out.println("Sorry, your program is dead :("); 
     } 
    } 
} 

是否有可能做什麼,我需要什麼?

謝謝。

*注意:我不是要求從零開始創建圖表,只需要調整模板的大小,然後將某些單元格更改爲日期而不是編寫的數字。

回答

2

研究如何XLSX作品後,我能找到如何完成它。

//Call the partiarch to start drawing 
XSSFDrawing drawing = ((XSSFSheet)currentSheet).createDrawingPatriarch(); 
//Create CTMarket for anchor 
CTMarker chartEndCoords = CTMarker.Factory.newInstance(); 
//The coordinates are set in columns and rows, not pixels. 
chartEndCoords.setCol(column); 
//Set Column offset 
chartEndCoords.setColOff(0); 
chartEndCoords.setRow(row); 
chartEndCoords.setRowOff(0); 
//drawing.getCTDrawing().getTwoCellAnchorArray(0).setFrom(chartStartCoords); 
drawing.getCTDrawing().getTwoCellAnchorArray(0).setTo(chartEndCoords); 

/* 
    This line of code allows to resize the chart: 
     The Patriarch is what allows to get control over the drawings, since 
     a chart is considered a graph in xlsx you can access it with getCTDrawing. 
     Each graph is stored in the tag getTwoCellAnchorArray, where the array position 
     is the chart you have; for example getTwoCellAnchorArray(3) would refer to the 
     forth graph within the sheet. 

     Each getTwoCellAnchorArray has several properties as FROM and TO, which define 
     where the existing graph starts and ends. 
*/ 

如果您有任何意見,請告訴我。

+0

你能分享一下你用來解決這個問題的資源嗎? – jahroy

1
  1. 給你的日期單元格,日期格式。 Apache poi date format

  2. POI無法修改圖形AFAIK。

+0

謝謝!編號1正是我需要的格式。 – StrayChild01

+0

由於格式不透明,POI對XSSF中的圖形/圖形的支持優於HSSF。也就是說,GSOC學生今年夏天添加了相當多的HSSF圖形支持,所以最近情況變得更好了! – Gagravarr

+0

@Gagravarr很高興知道!猜猜我們必須檢查出來... – Alfabravo