I am creating below conditional formatting rule in Apache POI.
Issue
Expected:
The formula should highlight only invalid values in column 'J'.
Actual:
But all values of the entire column 'J' get highlighted, even for valid values.
Formula
String kkf="IF(AND(NOT(ISBLANK(J4)),ISERROR(SUM(MATCH(FILTERXML(\"<t><s>\"&SUBSTITUTE(J4,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),FILTERXML(\"<t><s>\"&SUBSTITUTE(PossibleValues!$D$2,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),0))),\"\"),TRUE())";
Full Code
import java.util.ArrayList;
import org.apache.commons.io.FileUtils;
import org.json.CDL;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFHyperlink;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.ComparisonOperator;
import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.common.usermodel.Hyperlink;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
public class Red {
public static void main(String[] args) throws Exception{
String str="{\"rulesetgroupname\":\"Coastal122\",\"downloadtype\":\"Template\",\"rulesetid\":\"638a0ac02944f902b1eebab3\",\"rulesetversion\":\"0.1\",\"rulegroupid\":\"638a09f28bd88c16a76fa599\",\"product\":\"CAT\",\"ruletype\":\"ERWR\",\"dataobjects\":\"Location 24,Class Codes 24,BPP Covg 24,Building Covg 24,Building 24,Policy 24\",\"ruletemplateversion\":\"1\",\"ruleTemplaeResponseId\":\"638a09f28bd88c16a76fa599\",\"dataobject\":\"Location 24\",\"rulegroup\":\"CAT Testing122\",\"metadataheaders\":[\"Rule Name\",\"Rule Label\",\"Modified By\",\"Modified At\",\"Rule ID\",\"Rule Status (Add/Change/Expire/Verify)\",\"Effective Date [MM/DD/YYYY]\",\"Expiration Date [MM/DD/YYYY]\",\"Has Rule Changed?\"],\"conditionheaders\":[{\"label\":\"State\",\"type\":\"Collection\",\"name\":\"State\",\"dataobject\":\"Location 24\",\"values\":\"NC,SC,TX,VA,MA,GA,AL,IL,DE,NY,MS,NH,RI,ME,FL,MN,CT,NJ,MD\"},{\"label\":\"Counties\",\"type\":\"Collection\",\"name\":\"Counties\",\"dataobject\":\"Location 24\",\"values\":\"\"},{\"label\":\"Zip Codes\",\"type\":\"Collection\",\"name\":\"ZipCodes\",\"dataobject\":\"Location 24\",\"values\":\"\"}],\"outcomeheaders\":[{\"label\":\"Output\",\"type\":\"String\",\"name\":\"RuleCode\",\"dataobject\":\"Location 24\"}]}";
JSONObject output;
try {
output = new JSONObject(str);
String filename = "D:\\project\\excel\\color.xlsx" ;
XSSFWorkbook workbook = new XSSFWorkbook();
String rulegroup = output.getString("rulegroup");
String downloadtype = output.getString("downloadtype");
XSSFSheet sheet = workbook.createSheet("Ruleset");
sheet.setDefaultColumnWidth(10);
ArrayList<String> headers = new ArrayList<String>();
ArrayList<String> nameheaders = new ArrayList<String>();
// Top Element Font
Font font31 = workbook.createFont();
font31.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
font31.setBold(true);
XSSFCellStyle style12 = workbook.createCellStyle();
style12.setFillForegroundColor(HSSFColor.HSSFColorPredefined.PALE_BLUE.getIndex());
style12.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style12.setAlignment(HorizontalAlignment.CENTER);
style12.setVerticalAlignment(VerticalAlignment.CENTER);
style12.setBorderTop(BorderStyle.MEDIUM);
style12.setBorderBottom(BorderStyle.MEDIUM);
style12.setBorderLeft(BorderStyle.MEDIUM);
style12.setBorderRight(BorderStyle.MEDIUM);
style12.setWrapText(true);
style12.setFont(font31);
XSSFCellStyle style13 = workbook.createCellStyle();
style13.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_40_PERCENT.getIndex());
style13.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style13.setAlignment(HorizontalAlignment.CENTER);
style13.setVerticalAlignment(VerticalAlignment.CENTER);
style13.setBorderTop(BorderStyle.MEDIUM);
style13.setBorderBottom(BorderStyle.MEDIUM);
style13.setBorderLeft(BorderStyle.MEDIUM);
style13.setBorderRight(BorderStyle.MEDIUM);
style13.setWrapText(true);
style13.setFont(font31);
XSSFCellStyle style14 = workbook.createCellStyle();
Font font32 = workbook.createFont();
font32.setBold(true);
font32.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style14.setBorderTop(BorderStyle.MEDIUM);
style14.setBorderBottom(BorderStyle.MEDIUM);
style14.setBorderLeft(BorderStyle.MEDIUM);
style14.setBorderRight(BorderStyle.MEDIUM);
style14.setAlignment(HorizontalAlignment.CENTER);
style14.setVerticalAlignment(VerticalAlignment.CENTER);
style14.setWrapText(true);
style14.setFont(font32);
// Get Top elements
String product = output.getString("product");
String ruletype = output.getString("ruletype");
String dataobject = output.getString("dataobjects");
String rulesetid = output.getString("rulesetid");
String rulesetversion = output.getString("rulesetversion");
String rulegroupid = output.getString("rulegroupid");
String ruletemplateversion = output.getString("ruletemplateversion");
String rulesetgroupname = output.getString("rulesetgroupname");
XSSFRow rowhead = sheet.createRow((short) 0);
rowhead.createCell(0).setCellValue("Product/Process");
rowhead.getCell(0).setCellStyle(style14);
rowhead.createCell(1).setCellValue(product);
rowhead.getCell(1).setCellStyle(style13);
rowhead.createCell(2).setCellValue("RuleType");
rowhead.getCell(2).setCellStyle(style14);
rowhead.createCell(3).setCellValue(ruletype);
rowhead.getCell(3).setCellStyle(style13);
rowhead.createCell(4).setCellValue("DataObject");
rowhead.getCell(4).setCellStyle(style14);
rowhead.createCell(5).setCellValue(dataobject);
rowhead.getCell(5).setCellStyle(style13);
rowhead.createCell(6).setCellValue("RuleTemplate");
rowhead.getCell(6).setCellStyle(style14);
rowhead.createCell(7).setCellValue(rulegroup);
rowhead.getCell(7).setCellStyle(style13);
rowhead.createCell(8).setCellValue("RulesetID");
rowhead.getCell(8).setCellStyle(style14);
rowhead.createCell(9).setCellValue(rulesetid);
rowhead.getCell(9).setCellStyle(style13);
rowhead.createCell(10).setCellValue("RuleSetVersion");
rowhead.getCell(10).setCellStyle(style14);
rowhead.createCell(11).setCellValue(rulesetversion);
rowhead.getCell(11).setCellStyle(style13);
rowhead.createCell(12).setCellValue("RuleTemplateID");
rowhead.getCell(12).setCellStyle(style14);
rowhead.createCell(13).setCellValue(rulegroupid);
rowhead.getCell(13).setCellStyle(style13);
rowhead.createCell(14).setCellValue("RuleTemplateVersion");
rowhead.getCell(14).setCellStyle(style14);
rowhead.createCell(15).setCellValue(ruletemplateversion);
rowhead.getCell(15).setCellStyle(style13);
rowhead.createCell(16).setCellValue("RuleSetGroupName");
rowhead.getCell(16).setCellStyle(style14);
rowhead.createCell(17).setCellValue(rulesetgroupname);
rowhead.getCell(17).setCellStyle(style12);
rowhead.setHeightInPoints((2 * sheet.getDefaultRowHeightInPoints()));
JSONArray metadataheader = output.getJSONArray("metadataheaders");
JSONArray conditionheader = output.getJSONArray("conditionheaders");
JSONArray outcomeheader = output.getJSONArray("outcomeheaders");
Integer metheadcount = metadataheader.length();
Integer conheadcount = conditionheader.length();
Integer outheadcount = outcomeheader.length();
metadataheader.getString(0);
for (int i = 0; i < metadataheader.length(); i++) {
headers.add(metadataheader.getString(i));
nameheaders.add(metadataheader.getString(i));
}
for (int i = 0; i < conditionheader.length(); i++) {
JSONObject json = conditionheader.getJSONObject(i);
String conname = json.getString("label");
String contype = json.getString("type");
String dataobject1 = json.getString("dataobject");
contype = "[" + contype + "]";
String fnl = dataobject1 + "." + conname + " " + contype;
headers.add(fnl);
nameheaders.add(conname);
}
for (int i = 0; i < outcomeheader.length(); i++) {
JSONObject json = outcomeheader.getJSONObject(i);
// if(json.isEmpty()) {
// throw new Exception("Outcome Attributes filed should not be empty");
// }
String conname = json.getString("label");
String contype = json.getString("type");
String dataobject1 = json.getString("dataobject");
contype = "[" + contype + "]";
String fnl = dataobject1 + "." + conname + " " + contype;
headers.add(fnl);
nameheaders.add(conname);
}
// Merging Region
// HSSFRow merge = sheet.createRow((short)1);
Row row = sheet.createRow(1);
Cell cell = row.createCell(0);
cell.setCellValue("MetaData");
// Merging cells by providing cell index
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, metheadcount - 1));
Font font3 = workbook.createFont();
font3.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
font3.setBold(true);
XSSFCellStyle style = workbook.createCellStyle();
style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_GREEN.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setWrapText(true);
/*
* style.setBorderTop(BorderStyle.MEDIUM);
* style.setBorderBottom(BorderStyle.MEDIUM);
* style.setBorderLeft(BorderStyle.MEDIUM);
* style.setBorderRight(BorderStyle.MEDIUM);
*/
style.setFont(font3);
cell.setCellStyle(style);
// style.setFont(headerFont);
// style.setFillForegroundColor(IndexedColors.BLACK.getIndex());
Cell cell1 = row.createCell(metheadcount);
cell1.setCellValue("Conditional Attributes");
if (conheadcount > 1) {
sheet.addMergedRegion(new CellRangeAddress(1, 1, metheadcount, metheadcount + conheadcount - 1));
}
XSSFCellStyle style1 = workbook.createCellStyle();
Font font1 = workbook.createFont();
font1.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
font1.setBold(true);
style1.setFont(font1);
style1.setWrapText(true);
style1.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_ORANGE.getIndex());
style1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style1.setAlignment(HorizontalAlignment.CENTER);
style1.setVerticalAlignment(VerticalAlignment.CENTER);
/*
* style1.setBorderTop(BorderStyle.MEDIUM);
* style1.setBorderBottom(BorderStyle.MEDIUM);
* style1.setBorderLeft(BorderStyle.MEDIUM);
* style1.setBorderRight(BorderStyle.MEDIUM);
*/
cell1.setCellStyle(style1);
Cell cell2 = row.createCell(metheadcount + conheadcount);
cell2.setCellValue("Outcome Attributes");
if (outheadcount > 1) {
sheet.addMergedRegion(new CellRangeAddress(1, 1, metheadcount + conheadcount,
metheadcount + conheadcount + outheadcount - 1));
}
XSSFCellStyle style2 = workbook.createCellStyle();
Font font2 = workbook.createFont();
font2.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
font2.setBold(true);
style2.setFont(font2);
style2.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_CORNFLOWER_BLUE.getIndex());
style2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style2.setAlignment(HorizontalAlignment.CENTER);
style2.setVerticalAlignment(VerticalAlignment.CENTER);
style2.setWrapText(true);
/*
* style2.setBorderTop(BorderStyle.MEDIUM);
* style2.setBorderBottom(BorderStyle.MEDIUM);
* style2.setBorderLeft(BorderStyle.MEDIUM);
* style2.setBorderRight(BorderStyle.MEDIUM);
*/
cell2.setCellStyle(style2);
row.setHeightInPoints((2 * sheet.getDefaultRowHeightInPoints()));
/*
* HSSFCellStyle style22 = workbook.createCellStyle(); Font font22 =
* workbook.createFont();
* font22.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
* font22.setBold(true); style22.setFont(font22);
* style22.setAlignment(HorizontalAlignment.CENTER);
*/
XSSFCellStyle style22 = workbook.createCellStyle();
Font font22 = workbook.createFont();
font22.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
font22.setBold(true);
style22.setFont(font22);
style22.setBorderTop(BorderStyle.MEDIUM);
style22.setBorderBottom(BorderStyle.MEDIUM);
style22.setBorderLeft(BorderStyle.MEDIUM);
style22.setBorderRight(BorderStyle.MEDIUM);
style22.setWrapText(true);
// style22.setFillForegroundColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());
// style22.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style22.setAlignment(HorizontalAlignment.CENTER);
XSSFRow rowheader = sheet.createRow((short) 2);
for (int z = 0; z < headers.size(); z++) {
rowheader.createCell(z).setCellValue(headers.get(z));
String metaDataCellValue = rowheader.getCell(z).getStringCellValue();
if(metaDataCellValue.equals("Rule Name") || metaDataCellValue.equals("Modified By") ||
metaDataCellValue.equals("Modified At") || metaDataCellValue.equals("Rule ID")) {
rowheader.getCell(z).setCellStyle(style13);
} else {
rowheader.getCell(z).setCellStyle(style22);
}
}
rowheader.setHeightInPoints((2 * sheet.getDefaultRowHeightInPoints()));
// Get Details
DataFormatter formatter = new DataFormatter();
if (downloadtype.equalsIgnoreCase("rulesets")) {
JSONArray values = output.getJSONArray("values");
if (!values.isEmpty()) {
short valcell = 3;
for (int val = 0; val < values.length(); val++) {
XSSFRow rowheader2 = sheet.createRow((short) valcell + val);
try {
JSONObject firstvals = values.getJSONObject(val);
JSONArray methead1 = firstvals.optJSONArray("metadata");
JSONArray conhead1 = firstvals.optJSONArray("condition");
JSONArray outhead1 = firstvals.optJSONArray("outcome");
for (int i = 0; i < methead1.length(); i++) {
JSONObject json = methead1.getJSONObject(i);
String val23 = json.get("value").toString();
String name = "";
if (!json.isNull("label")) {
name = (json.getString("label"));
} else {
name = (json.getString("name"));
}
int index = nameheaders.indexOf(name);
rowheader2.createCell(index).setCellValue(val23);
}
for (int y = 0; y < conhead1.length(); y++) {
JSONObject json = conhead1.getJSONObject(y);
String val23 = json.get("value").toString();
String name = "";
if (!json.isNull("label")) {
name = (json.getString("label"));
} else {
name = (json.getString("name"));
}
String oper = (json.getString("operator"));
if (oper.equalsIgnoreCase("not in")) {
val23 = "NOT IN(" + val23 + ")";
} else if (oper.equalsIgnoreCase("neq")) {
val23 = "NOT EQUALS(" + val23 + ")";
} else if (oper.equalsIgnoreCase(">") || oper.equalsIgnoreCase("GT") ) {
val23 = ">" + val23;
} else if (oper.equalsIgnoreCase(">=") || oper.equalsIgnoreCase("GTE")) {
val23 = ">=" + val23;
}else if (oper.equalsIgnoreCase("<") || oper.equalsIgnoreCase("LT")) {
val23 = "<" + val23;
}
else if ( oper.equalsIgnoreCase("<=") || oper.equalsIgnoreCase("LTE")) {
val23 = "<=" + val23;
}
int index = nameheaders.indexOf(name);
if (index > 0) {
rowheader2.createCell(index).setCellValue(val23);
}
}
for (int za = 0; za < outhead1.length(); za++) {
JSONObject json = outhead1.getJSONObject(za);
String val23 = json.get("value").toString();
String name = "";
if (!json.isNull("label")) {
name = (json.getString("label"));
} else {
name = (json.getString("name"));
}
int index = nameheaders.indexOf(name);
if (index > 0) {
rowheader2.createCell(index).setCellValue(val23);
}
}
} catch (JSONException e) {
e.printStackTrace();
String error = e.getMessage();
throw new Exception(error);
} catch (Exception e) {
// String error = e.getMessage();
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
} //
}
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateAll();
// Duplicate Highlighter
String lcollett = "";
String csv1 = "";
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
int s1 = sheet.getNumMergedRegions();
for (int i = 0; i < s1; i++) {
CellRangeAddress region = sheet.getMergedRegion(i);
int colIndex = region.getFirstColumn();
int rowNum = region.getFirstRow();
String val1 = formatter.formatCellValue(sheet.getRow(rowNum).getCell(colIndex));
if (val1.contains("MetaData")) {
int fcol = sheet.getMergedRegion(i).getFirstColumn();
int lcol = sheet.getMergedRegion(i).getLastColumn();
lcollett = CellReference.convertNumToColString(lcol);
for (i = fcol; i <= lcol; i++) {
sheet.autoSizeColumn(i);
}
}
}
for (int i = 0; i < s1; i++) {
CellRangeAddress region = sheet.getMergedRegion(i);
int colIndex = region.getFirstColumn();
int rowNum = region.getFirstRow();
String val1 = formatter.formatCellValue(sheet.getRow(rowNum).getCell(colIndex));
ArrayList<String> xsdf = new ArrayList<String>();
if (val1.contains("Conditional")) {
int fcol = sheet.getMergedRegion(i).getFirstColumn();
int lcol = sheet.getMergedRegion(i).getLastColumn();
String fcollett = "";
lcollett = CellReference.convertNumToColString(lcol);
for (i = fcol; i <= lcol; i++) {
fcollett = CellReference.convertNumToColString(i);
if (i == lcol) {
xsdf.add("$" + fcollett + "$4:$" + fcollett + "$10000,\"*\"&$" + fcollett + "4&\"*\"");
} else {
xsdf.add("$" + fcollett + "$4:$" + fcollett + "$10000,$" + fcollett + "4");
}
sheet.autoSizeColumn(i);
}
csv1 = String.join(",", xsdf);
csv1 = "COUNTIFS(" + csv1 + ")>1";
}
}
for (int i = 0; i < s1; i++) {
CellRangeAddress region = sheet.getMergedRegion(i);
int colIndex = region.getFirstColumn();
int rowNum = region.getFirstRow();
String val1 = formatter.formatCellValue(sheet.getRow(rowNum).getCell(colIndex));
if (val1.contains("Outcome")) {
int fcol = sheet.getMergedRegion(i).getFirstColumn();
int lcol = sheet.getMergedRegion(i).getLastColumn();
lcollett = CellReference.convertNumToColString(lcol);
for (i = fcol; i <= lcol; i++) {
sheet.autoSizeColumn(i);
}
}
}
ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(csv1);
org.apache.poi.ss.usermodel.FontFormatting font = rule1.createFontFormatting();
font.setFontStyle(false, true);
font.setFontColorIndex(IndexedColors.BLUE.index);
String cellrangeadd = "A4:" + lcollett + "10000";
CellRangeAddress[] regions = new CellRangeAddress[] { CellRangeAddress.valueOf(cellrangeadd) };
sheetCF.addConditionalFormatting(regions, rule1);
// Sheet 3
SheetConditionalFormatting sheetCFa = sheet.getSheetConditionalFormatting();
XSSFSheet sheet21 = workbook.createSheet("PossibleValues");
sheet21.setColumnWidth(0, 20 * 256);
sheet21.setColumnWidth(1, 50 * 256);
XSSFRow rowhead33 = sheet21.createRow((short) 0);
rowhead33.createCell(0).setCellValue("DataObject");
rowhead33.getCell(0).setCellStyle(style14);
rowhead33.createCell(1).setCellValue("AttributeName");
rowhead33.getCell(1).setCellStyle(style14);
rowhead33.createCell(2).setCellValue("DataType");
rowhead33.getCell(2).setCellStyle(style14);
rowhead33.createCell(3).setCellValue("PossibleValues");
rowhead33.getCell(3).setCellStyle(style14);
int attcell=1;
ArrayList<String> xkdf = new ArrayList<String>();
for (int i = 0; i < conditionheader.length(); i++) {
JSONObject json = conditionheader.getJSONObject(i);
String conname = json.getString("label");
String contype = json.getString("type");
String dataobject1 = json.getString("dataobject");
String pv = json.getString("values");
String contypea = "[" + contype + "]";
String fnl = dataobject1 + "." + conname + " " + contypea;
xkdf.add(fnl);
XSSFRow rowhead334 = sheet21.createRow((short) attcell + i);
rowhead334.createCell(0).setCellValue(dataobject1);
rowhead334.createCell(1).setCellValue(conname);
rowhead334.createCell(2).setCellValue(contype);
rowhead334.createCell(3).setCellValue(pv);
}
String kkf = "IF(AND(NOT(ISBLANK(J4)),ISERROR(SUM(MATCH(FILTERXML(\"<t><s>\"&SUBSTITUTE(J4,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),FILTERXML(\"<t><s>\"&SUBSTITUTE(PossibleValues!$D$2,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),0))),\"\"),TRUE())";
ConditionalFormattingRule rule13 = sheetCF.createConditionalFormattingRule(kkf);
org.apache.poi.ss.usermodel.FontFormatting font535 = rule13.createFontFormatting();
font535.setFontStyle(false, true);
font535.setFontColorIndex(IndexedColors.RED.index);
String cellrangeadd2 = "J4:J10000";
CellRangeAddress[] regionssd = new CellRangeAddress[] { CellRangeAddress.valueOf(cellrangeadd2) };
sheetCF.addConditionalFormatting(regionssd, rule13);
FileOutputStream fileOut = new FileOutputStream(filename);
workbook.write(fileOut);
fileOut.close();
workbook.close();
System.out.println("Your excel file has been generated!");
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Required manual post-production in Excel
Now I did the below steps
Add three values in column 'J' named "State". All cells are getting highlighted, see image below:
Click Conditional Formatting > Manage Rules > Select Rule (Format Red) > Edit Rules > OK > Apply > OK
After this action the column values are getting highlighted correctly.
Question
Is there anything I missed in my Java code?
How do I avoid this manual activity in Excel?
Short answer
The problem is with the FILTERXML function used in your conditional formatting. This should be prefixed _xlfn in XML sheet storage. To make it work your formula should be changed to following:
String kkf = "IF(AND(NOT(ISBLANK(J4)),ISERROR(SUM(MATCH(_xlfn.FILTERXML(\"<t><s>\"&SUBSTITUTE(J4,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),_xlfn.FILTERXML(\"<t><s>\"&SUBSTITUTE(PossibleValues!$D$2,\",\",\"</s><s>\")&\"</s></t>\",\"//s\"),0))),\"\"),TRUE())";
Reason
FILTERXML function was introduced in Excel 2013. So it was introduced after Microsoft had published the Office Open XML file format for Microsoft Office files in 2006 for Office 2007. To mark such later introduced functions, Microsoft decided to prefix them with _xlfn in XML storage. After reading the XML, the Excel GUI knows whether the function is known in that Excel version or not. If yes, the prefix gets removed and the function name gets localized (e.g. in German Excel: to XMLFILTER). If not, the prefix remains and the user also knows that this function is unknown in that Excel version. See Issue: An _xlfn. prefix is displayed in front of a formula.
Why we need the storage formula version?
In Apache POI Cell.setCellFormula as well as SheetConditionalFormatting.createConditionalFormattingRule sets the formula string into the XML directly. So that string must be exactly as it shall be stored in XML.
Learn more about this by inspecting the file-formats
Office Open XML files, and so also *.xlsx files, are ZIP archives containing XML files and other files into a specific directory structure. So one simply can unzip a *.xlsx file to have a look into.
So after creating your color.xlsx using your code, unzip it and have a look into xl/worksheets/sheet1.xml.
You will find something like:
<conditionalFormatting sqref="J4:J10000">
<cfRule type="expression" dxfId="1" priority="2">
<formula>
<![CDATA[ IF(AND(NOT(ISBLANK(J4)),ISERROR(SUM(MATCH(FILTERXML("<t><s>"&SUBSTITUTE(J4,",","</s><s>")&"</s></t>","//s"),FILTERXML("<t><s>"&SUBSTITUTE(PossibleValues!$D$2,",","</s><s>")&"</s></t>","//s"),0))),""),TRUE()) ]]>
</formula>
</cfRule>
</conditionalFormatting>
And this does not work in Excel.
Now open the color.xlsx in Excel and make it work. Then save the the color.xlsx, unzip it again and have a look into xl/worksheets/sheet1.xml.
You will find something like:
<x14:conditionalFormattings>
<x14:conditionalFormatting xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">
<x14:cfRule type="expression" priority="2" id="{00000000-000E-0000-0000-000002000000}">
<xm:f>IF(AND(NOT(ISBLANK(J4)),ISERROR(SUM(MATCH(_xlfn.FILTERXML("<t><s>"&SUBSTITUTE(J4,",","</s><s>")&"</s></t>","//s"),_xlfn.FILTERXML("<t><s>"&SUBSTITUTE(PossibleValues!$D$2,",","</s><s>")&"</s></t>","//s"),0))),""),TRUE())</xm:f>
...
</x14:cfRule>
...
</x14:conditionalFormatting>
</x14:conditionalFormattings>
This shows the _xlfn prefix before FILTERXML in formula string.
It also shows that a totally different version of conditional formatting is used. But that's a secondary problem. The prefixed version of the formula string also works using as formula string within the old version of conditionalFormatting. But, of course that is not guaranteed in all cases. So to be on save side for all cases, one of two possibilities must be given:
either one avoids using all Excel functions introduced after publishing Office Open XML in 2006 (Office 2007)
or Apache POI has to fully support all changes Microsoft made after publishing Office Open XML in 2006 (Office 2007).
To fulfill the latter Apache POI is far away. It not even supports all features of Office 2007 up to now.
If using VBA is an acceptable solution for you, then a possible solution would be to create an .xlsm file containing the functions needed for conditional formatting.
Create manually the color.xlsm file
Add the 2 empty sheets "Ruleset" and "PossibleValues"
Open VBA editor
In sheet "Ruleset" add following Sub:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("$j$4:$j$1000")) Is Nothing Then
Highlight Target
End If
End Sub
Create a VBA Module and add following Sub...
Sub Highlight(ByVal Cell As Range)
Dim Entry() As String
Entry = Split(Cell.Value, ",")
Dim StatesString As String
StatesString = UCase(Worksheets("PossibleValues").Range("D2").Value)
Dim States() As String
States = Split(StatesString, ",")
Dim Matches As Integer
Matches = 0
For EntryIdx = 0 To UBound(Entry)
If (IsInArray(Entry(EntryIdx), States)) Then
Matches = Matches + 1
End If
Next EntryIdx
If (UBound(Entry) + 1 = Matches) Then
Cell.Font.Color = vbBlack
Else
Cell.Font.Color = vbRed
End If End Sub
...and the following function:
Private Function IsInArray(valToBeFound As Variant, arr As Variant) As Boolean
'DEVELOPER: Ryan Wells (wellsr.com)
'DESCRIPTION: Function to check if a value is in an array of values
'INPUT: Pass the function a value to search for and an array of values of any data type.
'OUTPUT: True if is in array, false otherwise
Dim element As Variant
On Error GoTo IsInArrayError: 'array is empty
For Each element In arr
If element = valToBeFound Then
IsInArray = True
Exit Function
End If
Next element
Exit Function
IsInArrayError:
On Error GoTo 0
IsInArray = False
End Function
Finally, you will need to adapt your code to open this manually created .xlsm file rather than creating it programmatically.
Hope it helps
I want to clone an Excel sheet and all of its contents. I tried the XSSFWorkbook cloneSheet method, but it seems the workbook is corrupted if my sheet contains an Excel table. See the examle workbook below with a simple table:
When I try to open the output workbook, I get a prompt telling me that the file is broken and needs to be repaired. If I recover the workbook, it is clear the table has not been copied correctly; the original totals row is now a data row.
try (InputStream is = Table.class.getResourceAsStream("table.xlsx")) {
XSSFWorkbook workbook = new XSSFWorkbook(is);
workbook.cloneSheet(0, "Test");
try (OutputStream fileOut = new FileOutputStream("table-2.xlsx")) {
workbook.write(fileOut);
}
} catch (IOException e) {
e.printStackTrace();
}
How I would go about copying this sheet? Any help is appreciated!
XSSFWorkbook.cloneSheet clones a sheet. But it does not considering the possible defined tables in it. It simply clones the table references. But two table-ranges in sheets cannot refer to the same table reference. The tables itself needs to be cloned. That's why the corrupted workbook as result.
I've tried to solve this by programming a method cloneTables(XSSFSheet sheet) which simply creates clones of each table in a sheet which then refer to their own table reference each. I consider table styles, auto-filter, a totals-row and calculated column formulas. I hope I have not overlooked something, but I doubt that.
The code its tested and works using current apache poi 5.2.2.
It contains fixes for following bugs too:
XSSFTable.updateHeaders fails in Excel workbooks created using current Excel versions. This is because of the test row.getCTRow().validate() which always will be false because of the usage of new name spaces. See Renaming headers of XSSFTable with Apache Poi leads to corrupt XLSX-file.
XSSFSheet.removeTable does not remove the links to the table part reference from the sheet.
Complete example to test:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
class ExcelCloneSheetHavingTable {
static void updateHeaders(XSSFTable table) {
XSSFSheet sheet = (XSSFSheet)table.getParent();
CellReference ref = table.getStartCellReference();
if (ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
DataFormatter formatter = new DataFormatter();
if (row != null /*&& row.getCTRow().validate()*/) { // see bug: https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
int cellnum = firstHeaderColumn;
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns ctTableColumns = table.getCTTable().getTableColumns();
if(ctTableColumns != null) {
for (org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn col : ctTableColumns.getTableColumnList()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
String colName = formatter.formatCellValue(cell);
colName = colName.replace("\n", "_x000a_");
colName = colName.replace("\r", "_x000d_");
col.setName(colName);
}
cellnum++;
}
}
}
//tableColumns = null;
//columnMap = null;
//xmlColumnPrs = null;
//commonXPath = null;
try {
java.lang.reflect.Field tableColumns = XSSFTable.class.getDeclaredField("tableColumns");
tableColumns.setAccessible(true);
tableColumns.set(table, null);
java.lang.reflect.Field columnMap = XSSFTable.class.getDeclaredField("columnMap");
columnMap.setAccessible(true);
columnMap.set(table, null);
java.lang.reflect.Field xmlColumnPrs = XSSFTable.class.getDeclaredField("xmlColumnPrs");
xmlColumnPrs.setAccessible(true);
xmlColumnPrs.set(table, null);
java.lang.reflect.Field commonXPath = XSSFTable.class.getDeclaredField("commonXPath");
commonXPath.setAccessible(true);
commonXPath.set(table, null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
static String getSubtotalFormulaStartFromTotalsRowFunction(int intTotalsRowFunction) {
final int INT_NONE = 1;
final int INT_SUM = 2;
final int INT_MIN = 3;
final int INT_MAX = 4;
final int INT_AVERAGE = 5;
final int INT_COUNT = 6;
final int INT_COUNT_NUMS = 7;
final int INT_STD_DEV = 8;
final int INT_VAR = 9;
final int INT_CUSTOM = 10;
String subtotalFormulaStart = null;
switch (intTotalsRowFunction) {
case INT_NONE:
subtotalFormulaStart = null;
break;
case INT_SUM:
subtotalFormulaStart = "SUBTOTAL(109";
break;
case INT_MIN:
subtotalFormulaStart = "SUBTOTAL(105";
break;
case INT_MAX:
subtotalFormulaStart = "SUBTOTAL(104";
break;
case INT_AVERAGE:
subtotalFormulaStart = "SUBTOTAL(101";
break;
case INT_COUNT:
subtotalFormulaStart = "SUBTOTAL(103";
break;
case INT_COUNT_NUMS:
subtotalFormulaStart = "SUBTOTAL(102";
break;
case INT_STD_DEV:
subtotalFormulaStart = "SUBTOTAL(107";
break;
case INT_VAR:
subtotalFormulaStart = "SUBTOTAL(110";
break;
case INT_CUSTOM:
subtotalFormulaStart = null;
break;
default:
subtotalFormulaStart = null;
}
return subtotalFormulaStart;
}
static void cloneTables(XSSFSheet sheet) {
for (XSSFTable table : sheet.getTables()) {
// clone table; XSSFTable.setArea fails and throws exception for too small tables
XSSFTable clonedTable = null;
int rowCount = (table.getArea().getLastCell().getRow() - table.getArea().getFirstCell().getRow()) + 1;
int headerRowCount = table.getHeaderRowCount(); if (headerRowCount == 0) headerRowCount = 1;
int minimumRowCount = 1 + headerRowCount + table.getTotalsRowCount();
if (rowCount >= minimumRowCount) {
clonedTable = sheet.createTable(table.getArea());
}
if (clonedTable != null) {
//clonedTable.updateHeaders(); // don't work, see bug: https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
updateHeaders(clonedTable);
// clone style
clonedTable.setStyleName(table.getStyleName());
XSSFTableStyleInfo style = (XSSFTableStyleInfo)table.getStyle();
XSSFTableStyleInfo clonedStyle = (XSSFTableStyleInfo)clonedTable.getStyle();
if (style != null && clonedStyle != null) {
clonedStyle.setShowColumnStripes(style.isShowColumnStripes());
clonedStyle.setShowRowStripes(style.isShowRowStripes());
clonedStyle.setFirstColumn(style.isShowFirstColumn());
clonedStyle.setLastColumn(style.isShowLastColumn());
}
//clone autofilter
clonedTable.getCTTable().setAutoFilter(table.getCTTable().getAutoFilter());
//clone totalsrow
int totalsRowCount = table.getTotalsRowCount();
if (totalsRowCount == 1) { // never seen more than one totals row
XSSFRow totalsRow = sheet.getRow(clonedTable.getEndCellReference().getRow());
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
clonedTableCol.setTotalsRowFunction(tableCol.getTotalsRowFunction());
int intTotalsRowFunction = clonedTableCol.getTotalsRowFunction().intValue();
sheet.getWorkbook().setCellFormulaValidation(false);
if (intTotalsRowFunction == 10) { //custom
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableFormula totalsRowFormula = tableCol.getTotalsRowFormula();
clonedTableCol.setTotalsRowFormula(totalsRowFormula);
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(totalsRowFormula.getStringValue());
} else if (intTotalsRowFunction == 1) { //none
//totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setBlank();
} else {
String subtotalFormulaStart = getSubtotalFormulaStartFromTotalsRowFunction(intTotalsRowFunction);
if (subtotalFormulaStart != null)
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(subtotalFormulaStart + "," + clonedTable.getName() +"[" + clonedTableCol.getName()+ "])");
}
}
}
}
// clone calculated column formulas
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
if (tableCol.getCalculatedColumnFormula() != null) {
clonedTableCol.setCalculatedColumnFormula(tableCol.getCalculatedColumnFormula());
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableFormula calculatedColumnFormula = clonedTableCol.getCalculatedColumnFormula();
String formula = tableCol.getCalculatedColumnFormula().getStringValue();
String clonedFormula = formula.replace(table.getName(), clonedTable.getName());
calculatedColumnFormula.setStringValue(clonedFormula);
int rFirst = clonedTable.getStartCellReference().getRow() + clonedTable.getHeaderRowCount();
int rLast = clonedTable.getEndCellReference().getRow() - clonedTable.getTotalsRowCount();
int c = clonedTable.getStartCellReference().getCol() + i;
sheet.getWorkbook().setCellFormulaValidation(false);
for (int r = rFirst; r <= rLast; r++) {
XSSFRow row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellFormula(clonedFormula);
}
}
}
}
}
// remove old table; do that even if XSSFsheet.createTable failed, because a one-cell-table doesn't make any sense
String rId = sheet.getRelationId(table);
sheet.removeTable(table);
// remove links to the table part reference
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts tblParts = sheet.getCTWorksheet().getTableParts();
if (tblParts != null && tblParts.getTablePartList().size() > 0) {
for (int i = 0; i < tblParts.getTablePartList().size(); i++) {
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart tblPart = tblParts.getTablePartArray​(i);
if(tblPart.getId().equals(rId)) {
tblParts.removeTablePart​(i);
}
}
}
}
}
public static void main(String[] args) throws Exception {
try (Workbook workbook = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));
FileOutputStream out = new FileOutputStream("SAMPLE_NEW.xlsx")) {
XSSFSheet sheet = ((XSSFWorkbook)workbook).cloneSheet(0, "Test");
cloneTables(sheet);
workbook.write(out);
}
}
}
This code needs the full jar of all of the schemas, which is poi-ooxml-full-5.2.2.jar for apache poi 5.2.2, as mentioned in FAQ. Note, since apache poi 5.* the formerly used ooxml-schemas-*.jar cannot be used anymore. There must not be any ooxml-schemas-*.jar in class path when using apache poi 5.*.
Note, you need this additional. The file names poi-ooxml-5.2.2.jar and poi-ooxml-lite-5.2.2.jar respective poi-ooxml-full-5.2.2.jar are misleading. The *-lite*.jar respective *-full*.jar do not replace, but complement the poi-ooxml-5.2.2.jar.
Is there any built in function that can be used to easily compare two rows in an Excel file. I am using Apache POI.
try {
Workbook wb1 = WorkbookFactory.create(new File(file1Path));
Sheet sheet1 = wb1.getSheetAt(0);
Workbook wb2 = WorkbookFactory.create(new File(file2Path));
Sheet sheet2 = wb2.getSheetAt(0);
for (Row myrow : sheet1) {
if (myrow.getRowNum() == 0) {
// add entire row to a sheet for 'found in file 1 but not file 2' -> sheet 0
write(myrow, output_filename_path, dstSheetNumberInOutputFile);
continue;
}
// look for this key in the other sheet
for (Row otherRow : sheet2) {
if (rowsAreEqual(myrow, otherRow)) {
write(myrow, output_filename_path, dstSheetNumberInOutputFile);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
So I have an if statement that has the function rowsAreEqual() needs to compare equality of the two rows. How can I make the rowsAreEqual() function?
I tried this but hasn't worked:
private static boolean rowsAreEqual(Row myrow, Row otherRow) {
int equalCount = 0;
System.out.println("last cell num: " + myrow.getLastCellNum());
for(int i=0; i < myrow.getLastCellNum(); i++){
if(myrow.getCell(i) == otherRow.getCell(i)){
equalCount++;
System.out.println("Cells are the same: " + myrow.getCell(i) + " && " + otherRow.getCell(i));
}
}
if(equalCount == myrow.getLastCellNum()){
return true;
}
return false;
}
I figured it out like this. I had to make an extra function called getCellContentsAsString() so that I could compare the cells correctly:
private static boolean rowsAreEqual(Row myrow, Row otherRow) {
int equalCount = 0;
System.out.println("last cell num: " + myrow.getLastCellNum());
for(int i=0; i < myrow.getLastCellNum(); i++){
System.out.println(myrow.getCell(i) + " is the cell content in file1");
System.out.println(otherRow.getCell(i) + " is the cell content in file2");
Cell c1 = myrow.getCell(i);
Cell c2 = otherRow.getCell(i);
String s1 = getCellContentAsString(c1);
String s2 = getCellContentAsString(c2);
if(s1.equals(s2)){
equalCount++;
System.out.println("Cells are the same: " + myrow.getCell(i) + " && " + otherRow.getCell(i));
}
}
if(equalCount == myrow.getLastCellNum()){
return true;
}
return false;
}
private static String getCellContentAsString(Cell cell) {
String data = null;
if(cell.getCellType()==CellType.STRING) {
data = cell.getStringCellValue();
}
else if(cell.getCellType()==CellType.NUMERIC) {
data = String.valueOf(cell.getNumericCellValue());
}
return data;
}
You could abstract to comparing a range of cells.
This would allow you comparing either rows or columns, or individual regions (e.g. A1:Z256) - a so called Range.
So the object to compare - to be equal in contents - is CellRange.
In Java the boolean equals() method of any object relies on their int hashCode() function. In a utility-class called RangeContentsUtils you could implement both:
public class RangeContentsUtils {
public static boolean contentsEquals(CellRange rangeA, CellRange rangeB) {
if (rangeA == null || rangeB == null) {
return false;
}
if (rangeA.size() != rangeB.size()) {
return false;
}
// alternative would be:
// return stringContentsOf(rangeA).hashCode() == stringContentsOf(rangeB).hashCode();
return contentsToString(rangeA).equals(contentsToString(rangeB));
}
public static String contentsToString(CellRange range) {
StringBuilder sb = new StringBuilder();
Iterator<Cell> cellIterator = range.iterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch(cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
sb.append(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
sb.append(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
sb.append(cell.getStringCellValue());
break;
}
sb.append("\0"); // use NUL char as cell-separator
}
return sb.toString();
}
}
Now your row-comparison could use this utility class.
See also:
Compare specific row or column of xls sheet using java and Apache POI
I am using APACHE POI 3.0 to add sheets to existing excel sheet. It works fine.
But as APACHE POI has limitations about making charts, I used a template excel file to create charts, which also worked fine, but this always result in new excel file.
If I have an existing excel sheet and I want to add a sheet, having charts, I am not able to do it. As, when I create charts, I use template file and it always makes a new excel file.
so I was wondering if there is any solution of it of adding sheets to excel, where the sheets have charts
public class TagBrowserSelection
{
private static String[] excelBarPlot_Template = { "","barPlot_1Panel_template.xlsx"};
private static String[] excelPieChart_Template = { "","pieChart_1Panel_template.xlsx"};
private static String[] excelPieAndBarPlot_Template = { "","pieAndBarChart_1Panel_template.xlsx"};
private static String REGEX = "";
static public boolean makeTagBrowserSelection(String strOutputFileName, ArrayList<TagBrowserChildPanel> childList, String sheetName, boolean addSheet, ArrayList<Boolean> chartAttributes)
{
// chart attributes
boolean addBarChart = chartAttributes.get(0);
boolean addPieChart = chartAttributes.get(1);
boolean addNoTag = chartAttributes.get(2);
boolean addZeros = chartAttributes.get(3);
REGEX = "^" + sheetName;
Pattern p = Pattern.compile(REGEX);
String[] templateArray = null;
if (addBarChart && addPieChart)
templateArray = excelPieAndBarPlot_Template;
else if (addBarChart)
templateArray = excelBarPlot_Template;
else if (addPieChart)
templateArray = excelPieChart_Template;
try
{
int number = childList.size();
XSSFWorkbook workbook = null;
XSSFWorkbook wb = null;
XSSFSheet sheet = null;
int col_num = 0;
int row_num = 0;
XSSFRow row = null;
XSSFCell cell = null;
// if adding sheet to existing excel file
if (addSheet)
{
FileInputStream fis = new FileInputStream(new File(strOutputFileName));
workbook = new XSSFWorkbook(fis);
fis.close();
// number of existing sheets in excel file
int numberOfSheets = workbook.getNumberOfSheets();
// check is sheetName exists already
if (isSheetExist(sheetName, workbook))
{
int counter = 1;
for (int ii = 0; ii < numberOfSheets; ii++)
{
Matcher m = p.matcher(workbook.getSheetName(ii));
if (m.find())
counter++;
}
sheetName = sheetName + " (" + counter + ")";
}
}
else
{
workbook = new XSSFWorkbook();
}
======================================================================
// if template file needs to be used(if bar chart/pie chart option is selected)
if (templateArray != null)
{
InputStream is = TagBrowserSelection.class.getClassLoader().getResourceAsStream(templateArray[number]);
wb = new XSSFWorkbook(OPCPackage.open(is));
sheet = wb.getSheetAt(0);
// wb.close();
}
else
{
sheet = workbook.createSheet(sheetName);
}
// Freeze top two row
// sheet.createFreezePane(0, 1, 0, 1);
// Filling up the workbook and performing the row/column formatting
for (TagBrowserChildPanel child : childList)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(0);
if (row == null)
row = sheet.createRow(0);
// Adding tag category name as header
String tagCategory = child.getSelectedCategory().getName();
cell = row.createCell(col_num);
cell.setCellValue(tagCategory);
row = sheet.getRow(1);
if (row == null)
row = sheet.createRow(1);
// Adding column headers
cell = row.createCell(col_num);
cell.setCellValue("tag");
cell = row.createCell(col_num + 1);
cell.setCellValue("counts");
row_num = 2;
// Adding tag category document summary(name and counts)
ArrayList<TagSummaryItem> tagSummary = child.getTagChartCounts();
for (int i = 0; i < tagSummary.size(); i++)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(row_num);
if (row == null)
row = sheet.createRow(row_num);
cell = row.createCell(col_num);
if (!addNoTag)
{
if (tagSummary.get(i).m_strTag == "[No Tag]")
continue;
}
if (!addZeros)
{
if (tagSummary.get(i).m_nCount == 0)
continue;
}
cell.setCellValue(tagSummary.get(i).m_strTag);
cell = row.createCell(col_num + 1);
cell.setCellValue(tagSummary.get(i).m_nCount);
row_num++;
}
// auto-size of tag column
sheet.autoSizeColumn(col_num);
col_num = col_num + 3;
}
FileOutputStream out = new FileOutputStream(strOutputFileName);
if (templateArray != null)
{
wb.setSheetName(0, sheetName);
wb.write(out);
wb.close();
}
else
{
workbook.write(out);
workbook.close();
}
out.close();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
Above is my code, its one code. I split into two sections. Section is the one which uses template to make chart excel sheet.
there's the method cloneSheet() in the HSSFWorkbook class. Try it.