Search code examples
excelconditional-statementsapache-poiprogress

How to create a Progress Bar within a cell using apache poi?


I would like to create a progress bar within a Excel-sheet cell. I must use Apache Poi library, but I do not know how to even start. (Something like this, but using the Java library) http://www.tech-recipes.com/rx/35064/excel-2013-create-progress-bars/

I guess I must put a conditional formating, but I do know how it works and I can not find a solution anywhere ... somebody can help me out?

Thanks in advance.


Solution

  • As you suggested, I've used your link to create an example xlsx and simply recreated the necessary xml structures, i.e. open the xlsx file as zip archive and have a look at xl/worksheets/sheet1.xml. Beside the poi-ooxml.jar you'll need the ooxml-schemas-1.1.jar.

    (tested with Libre Office 4.0, Excel Viewer 2010, POI 3.10-beta1)

    import java.io.FileOutputStream;
    import java.lang.reflect.*;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.*;
    import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
    
    public class Databar {
        public static void main(String[] args) throws Exception {
            Workbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet();
            for (int i=0; i<4; i++) {
                sheet.createRow(i).createCell(0).setCellValue(new int[]{12,38,93,42}[i]);
            }
    
            SheetConditionalFormatting cf = sheet.getSheetConditionalFormatting();
            XSSFConditionalFormattingRule xcfrule =
                (XSSFConditionalFormattingRule)cf.createConditionalFormattingRule("");
    
            Method m = XSSFConditionalFormattingRule.class.getDeclaredMethod("getCTCfRule");
            m.setAccessible(true);
            CTCfRule cfRule = (CTCfRule)m.invoke(xcfrule);
            cfRule.removeFormula(0); // cleanup
    
            cfRule.setType(STCfType.DATA_BAR);
            CTDataBar databar = cfRule.addNewDataBar();
            CTCfvo vfoMin = databar.addNewCfvo();
            vfoMin.setType(STCfvoType.NUM);
            vfoMin.setVal("0");
            CTCfvo vfoMax = databar.addNewCfvo();
            vfoMax.setType(STCfvoType.NUM);
            vfoMax.setVal("100");
            CTColor color = databar.addNewColor();
            color.setRgb(new byte[]{(byte)0xFF, 0x00, 0x00, (byte)0xFF});
    
            CellRangeAddress cra[] = {new CellRangeAddress(0, 3, 0, 0)};
            cf.addConditionalFormatting(cra, xcfrule);
    
            FileOutputStream fos = new FileOutputStream("databar-out.xlsx");
            wb.write(fos);
            fos.close();
        }
    }