1

Apache POI (XSSF) を使用してグラフのサイズを変更する方法があるかどうか疑問に思っています。現在、namedRanges を使用してさらにデータが挿入されると変化するグラフを持つ Excel テンプレートを使用しています。

すべてが正常に機能します。私が直面している唯一の問題は次のとおりです。

  • グラフは常に同じサイズのままなので、エントリが増えると、雑然としてグラフが役に立たなくなります。
  • 日付を使用していますが、チャートで日付を日/月 (17/10) として表すことができません。基本的に、2001 年 4 月 1 日の代わりに、36982 と書きます。

ワークブックの目的は、いくつかのジョブを一覧表示し、特定の日付に時間がかかったかどうかを確認することです。グラフは、経過時間の延長の発生を特定するのに役立ちます。ジョブの実行時間は、数秒から数時間の範囲になる場合があります。

これは私が使用しているコードです:

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 :(");
        }
    }
}

私が必要とすることは可能ですか?

ありがとう。

*注: 最初からグラフを作成するように求めているわけではありません。テンプレートに含まれているもののサイズを変更し、いくつかのセルを、書かれている数値ではなく日付に変更するだけで済みます。

4

2 に答える 2

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.   
*/

ご意見がありましたら、お知らせください。

于 2012-10-18T14:51:41.010 に答える
1
  1. 日付セル、日付形式を指定します。 Apache poi の日付形式

  2. POI はグラフィックを変更できません。

于 2012-10-17T18:15:38.140 に答える