如何在POI XSSFWorkbook中消除零值数据条

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在POI XSSFWorkbook中消除零值数据条相关的知识,希望对你有一定的参考价值。

我创建了一个XSSFWorkbook,将数据栏显示为官方示例。 http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java。我的问题是为什么零值也显示了标准,我该如何消除它? Screenshot

static void dataBars2(XSSFSheet sheet) {

		XSSFFont font = sheet.getWorkbook().createFont();
		font.setFontName("等线 Regular");
		font.setFontHeight(12.0);
		CellStyle cs = sheet.getWorkbook().createCellStyle();
		cs.setDataFormat((short) 10);
		cs.setAlignment(HorizontalAlignment.CENTER);
		cs.setBorderLeft(BorderStyle.THIN);
		cs.setBorderTop(BorderStyle.THIN);
		cs.setBorderRight(BorderStyle.THIN);
		cs.setBorderBottom(BorderStyle.THIN);
		cs.setLeftBorderColor(IndexedColors.BLACK.index);
		cs.setFont(font);
		CellStyle cs_m = sheet.getWorkbook().createCellStyle();
		cs_m.setDataFormat((short) 3);
		cs_m.setAlignment(HorizontalAlignment.CENTER);
		cs_m.setBorderLeft(BorderStyle.THIN);
		cs_m.setBorderTop(BorderStyle.THIN);
		cs_m.setBorderRight(BorderStyle.THIN);
		cs_m.setBorderBottom(BorderStyle.THIN);
		cs_m.setFont(font);

		CellStyle cs_header = sheet.getWorkbook().createCellStyle();

		cs_header.setBorderLeft(BorderStyle.THIN);
		cs_header.setBorderTop(BorderStyle.THIN);
		cs_header.setBorderRight(BorderStyle.THIN);
		cs_header.setBorderBottom(BorderStyle.THIN);

		XSSFColor color1 = new XSSFColor(new Color(218, 225, 240));
		cs_header.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		((XSSFCellStyle) cs_header).setFillForegroundColor(color1);

		cs_header.setAlignment(HorizontalAlignment.CENTER);

		Row r = sheet.createRow(0);
		Cell c00 = r.createCell(0);
		c00.setCellValue("Data Bars");
		c00.setCellStyle(cs_header);
		Cell c01 = r.createCell(1);
		c01.setCellStyle(cs_header);
		c01.setCellValue("Green Positive");

		List<Double> list = Arrays.asList(0.279, 0.252, 0.187, 0.128, 0.078, 0.043, 0.022, 0.012, 0.011, 0.0, 0.0);
		for (int i = 0; i <= 10; i++) {
			r = sheet.createRow(i + 1);
			Cell c0 = r.createCell(0);
			c0.setCellValue(10000 + i);
			c0.setCellStyle(cs_m);
			Cell c = r.createCell(1);
			c.setCellValue(list.get(i));
			c.setCellStyle(cs);
		}

		sheet.setColumnWidth(0, 3000);
		sheet.setColumnWidth(1, 5000);

		XSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();

		ExtendedColor colorA = sheet.getWorkbook().getCreationHelper().createExtendedColor();
		colorA.setARGBHex("FF80C279");
		CellRangeAddress[] regions1 = {CellRangeAddress.valueOf("B2:B12")};
		XSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(colorA);
		XSSFDataBarFormatting db1 = rule1.getDataBarFormatting();
		db1.getMinThreshold().setRangeType(RangeType.MIN);
		db1.getMaxThreshold().setRangeType(RangeType.MAX);
		sheetCF.addConditionalFormatting(regions1, rule1);
	}

PS:HSSFWorkbook没有显示具有相同数据的零值数据栏。

答案

显而易见的答案是将XSSFDataBarFormatting.setWidthMin设置为0.但这不起作用,因为它还没有实现。见XSSFDataBarFormatting.java

所以我们需要使用低级基础类org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataBar来做到这一点。

例:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFDataBarFormatting;

import org.apache.poi.ss.util.CellRangeAddress;

import java.io.FileOutputStream;

import java.lang.reflect.Field;

public class ConditionalFormattingDataBars {

 public static void applyDataBars(SheetConditionalFormatting sheetCF, String region, ExtendedColor color) throws Exception {
  CellRangeAddress[] regions = { CellRangeAddress.valueOf(region) };
  ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule(color);
  DataBarFormatting dbf = rule.getDataBarFormatting();
  dbf.getMinThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.MIN);
  dbf.getMaxThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.MAX);

  dbf.setWidthMin(0); //cannot work for XSSFDataBarFormatting, see https://svn.apache.org/viewvc/poi/tags/REL_4_0_1/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java?view=markup#l57
  dbf.setWidthMax(100); //cannot work for XSSFDataBarFormatting, see https://svn.apache.org/viewvc/poi/tags/REL_4_0_1/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java?view=markup#l64

  if (dbf instanceof XSSFDataBarFormatting) {
   Field _databar = XSSFDataBarFormatting.class.getDeclaredField("_databar");
   _databar.setAccessible(true);
   org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataBar ctDataBar =
    (org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataBar)_databar.get(dbf);
   ctDataBar.setMinLength(0);
   ctDataBar.setMaxLength(100);
  }

  sheetCF.addConditionalFormatting(regions, rule);
 }

 public static void main(String[] args) throws Exception {
  Workbook workbook = new XSSFWorkbook();

  Sheet sheet = workbook.createSheet("new sheet");

  java.util.List<Double> list = java.util.Arrays.asList(0.279, 0.252, 0.187, 0.128, 0.078, 0.043, 0.022, 0.012, 0.011, 0.0, 0.0);
  for (int i = 0; i < list.size(); i++) {
   sheet.createRow(i+1).createCell(1).setCellValue(list.get(i));
  }

  SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  ExtendedColor color = workbook.getCreationHelper().createExtendedColor();
  color.setARGBHex("FF80C279");
  applyDataBars(sheetCF, "B2:B12", color);

  sheet.setColumnWidth(1, 50*256);

  FileOutputStream out = new FileOutputStream("ConditionalFormattingDataBars.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();

 }
}

结果:

enter image description here

以上是关于如何在POI XSSFWorkbook中消除零值数据条的主要内容,如果未能解决你的问题,请参考以下文章

poi的XSSFWorkbook转SXSSFWorkbook发现的问题

Java-API-POI-Excel:XSSFWorkbook Documentation

收藏poi 使用模板创建一个XSSFWorkbook,为啥取不到row对象

使用POI操作Excel时new XSSFWorkbook ()报错java.lang.NoSuchMethodError解决方式

org.apache.poi.hssf.usermodel.HSSFWorkbookorg.apache.poi.xssf.usermodel.XSSFWorkbook excel2003 exce

poi 3.8生成excel2007时,debug到Workbook wb =new XSSFWorkbook();这一行报错