美文网首页
POI 条件格式 数据条 SheetConditionalFo

POI 条件格式 数据条 SheetConditionalFo

作者: Seymoure | 来源:发表于2021-12-13 00:26 被阅读0次

使用 POI 设置单元格条件格式 数据条,效果如图:


image.png

POI版本使用 4.1.2,
代码如下:

package com.example.poidemo.prosesscell;

import org.apache.poi.hssf.record.common.ExtendedColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFDataBarFormatting;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author longzhe
 * @Description 导出带进度条单元格的excel
 * @createTime 2021-12-12 22:37
 */
@RestController()
public class ProcessController {

    @GetMapping("/processCell")
    public void processCell(HttpServletResponse response) throws IOException {
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        SXSSFSheet sheet = workbook.createSheet("进度条测试");
        SXSSFRow row = sheet.createRow(0);
        // 单元格0
        SXSSFCell cell = row.createCell(0);
        cell.setCellValue(Double.valueOf("10086.123"));
        // 单元格1
        cell = row.createCell(1);
        cell.setCellValue(Double.valueOf("4386.345"));
        // 单元格2
        cell = row.createCell(2);
        cell.setCellValue(Double.valueOf("8000.82"));

        SheetConditionalFormatting formatting = sheet.getSheetConditionalFormatting();
        XSSFColor color = new XSSFColor(IndexedColors.LIGHT_BLUE, new DefaultIndexedColorMap());
        ConditionalFormattingRule rule = formatting.createConditionalFormattingRule(color);
        XSSFDataBarFormatting dataBarFormatting = (XSSFDataBarFormatting) rule.getDataBarFormatting();
        // 以下4行 可以设置具体的最大值最小值 而不是自动根据单元格范围自动取值
//        dataBarFormatting.getMinThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.NUMBER);
//        dataBarFormatting.getMaxThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.NUMBER);
//        dataBarFormatting.getMinThreshold().setValue(Double.valueOf("0"));
//        dataBarFormatting.getMaxThreshold().setValue(Double.valueOf("10086"));

        CellRangeAddress[] range = {
                CellRangeAddress.valueOf("A1:C1")
        };
        formatting.addConditionalFormatting(range,rule);

        response.setHeader("Content-type","application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        workbook.write(response.getOutputStream());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }
}

update 2021-12-15
如果仔细看数据条,会发现当单元格数字大于等于条件格式最大值时,颜色并没有填满整个单元格,而是在右边还缺少10%左右,这是由于XSSFWorkbook引起的。具体可以参考 https://svn.apache.org/viewvc/poi/tags/REL_4_0_1/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java?view=markup#l57

解决方式是

        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(dataBarFormatting);
        ctDataBar.setMinLength(0);
        ctDataBar.setMaxLength(100);

于是完整代码如下:

package com.example.poidemo.prosesscell;

import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFDataBarFormatting;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;

/**
 * @author longzhe
 * @Description 导出带进度条单元格的excel
 * @createTime 2021-12-12 22:37
 */
@RestController
public class ProcessController {

    @GetMapping("/processCell")
    public void processCell(HttpServletResponse response) throws IOException, NoSuchFieldException, IllegalAccessException {
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        SXSSFSheet sheet = workbook.createSheet("进度条测试");
        SXSSFRow row = sheet.createRow(0);
        // 单元格0
        SXSSFCell cell = row.createCell(0);
        cell.setCellValue(Double.valueOf("10086"));
        // 单元格1
        cell = row.createCell(1);
        cell.setCellValue(Double.valueOf("4386"));
        // 单元格2
        cell = row.createCell(2);
        cell.setCellValue(Double.valueOf("8000"));

        SheetConditionalFormatting formatting = sheet.getSheetConditionalFormatting();
        XSSFColor color = new XSSFColor(IndexedColors.LIGHT_BLUE, new DefaultIndexedColorMap());
        ConditionalFormattingRule rule = formatting.createConditionalFormattingRule(color);
        XSSFDataBarFormatting dataBarFormatting = (XSSFDataBarFormatting) rule.getDataBarFormatting();
        // 以下4行 可以设置具体的最大值最小值 而不是自动根据单元格范围自动取值
        dataBarFormatting.getMinThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.NUMBER);
        dataBarFormatting.getMaxThreshold().setRangeType(ConditionalFormattingThreshold.RangeType.NUMBER);
        dataBarFormatting.getMinThreshold().setValue(Double.valueOf(0));
        dataBarFormatting.getMaxThreshold().setValue(Double.valueOf(10085.9823));

        dataBarFormatting.setWidthMin(0);
        dataBarFormatting.setWidthMax(100);

        if (dataBarFormatting 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(dataBarFormatting);
            ctDataBar.setMinLength(0);
            ctDataBar.setMaxLength(100);
        }

        CellRangeAddress[] range = {
                CellRangeAddress.valueOf("A1:C1")
        };
        formatting.addConditionalFormatting(range,rule);

        response.setHeader("Content-type","application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        workbook.write(response.getOutputStream());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }

}

相关文章

  • POI 条件格式 数据条 SheetConditionalFo

    使用 POI 设置单元格条件格式 数据条,效果如图: POI版本使用 4.1.2,代码如下: update 202...

  • 16期EXECL学习第九天

    条件格式-扮靓报表 今天学习的条件格式。 三点收获:①数据条的用法,在条件格式里可以选取数据条来体现数据,更直观 ...

  • POI获取EXCEL时间格式数据

    记录一次POI读取excel列表数据时,获取到的数据是时间格式,导致数据出错问题 注意:POI判断自定义时间格式时...

  • 2019-03-07 用条件格式扮靓报表

    用条件格式扮靓报表 努力常态化! 什么是条件格式呢?其实就是让符合条件的单元格显示为预设的格式。根据条件使用数据条...

  • 数据录入

    第8节 Excel 数据录入 数据条让数据更直观 1. 设置数据条 2. 删除数据条 玩转条件格式---1突出显示...

  • 一张图表教你高逼格耍帅

    今晚的文全是干货,绝无水货。 最终效果 利用数据条美化数据 首先选中需要美化的数据-----找到条件格式下拉数据条...

  • 使用Apache POI导出Excel--大数量导出

    生成XLSX格式Excel文档大数据量导出 使用Apache POI导出Excel小结--导出XLS格式文档 使用...

  • java使用POI将数据导出放入Excel

    本文主要是将数据库取出的数据按照自定义的行列格式导出到excel中,POI则是实现我们需求所用到的技术。 POI介...

  • 2019-05-19 java使用POI将数据导出放入Exc

    本文主要是将数据库取出的数据按照自定义的行列格式导出到excel中,POI则是实现我们需求所用到的技术。 POI介...

  • 百度地图实现抓数据

    前瞻 该表的说明是:按照这个上面的搜索几乎能把地图所有POI的数据取出。我们的目标就是当输入几个关键条件就把符合条...

网友评论

      本文标题:POI 条件格式 数据条 SheetConditionalFo

      本文链接:https://www.haomeiwen.com/subject/knodfrtx.html