【POI操作WORD图表组合图】

POI操作WORD图表组合图

组合图

在这里插入图片描述

需要引入的maven包

 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
public static void chart(ProjectTargetEntity projectTargetEntity, XWPFDocument document) throws IOException, InvalidFormatException {
        //读取图形模板
        String pdfFilePath = "templates/chart.docx";
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(pdfFilePath);
        assert inputStream != null;
        XWPFDocument doc = new XWPFDocument(inputStream);
//        替换word模板数据
        List<FrequencyKPIValuesEntity> frequencyKPIValuesList = projectTargetEntity.getFrequencyKPIValuesList();
        for (FrequencyKPIValuesEntity frequencyKPIValuesEntity : frequencyKPIValuesList) {
            if (EmptyUtil.isFieldEmpty(frequencyKPIValuesEntity.getCurrentKPITargetValue())) {
                frequencyKPIValuesEntity.setCurrentKPITargetValue("0");
            }
            if (EmptyUtil.isFieldEmpty(frequencyKPIValuesEntity.getCurrentKPIActualValue())) {
                frequencyKPIValuesEntity.setCurrentKPIActualValue("0");
            }
            if (EmptyUtil.isFieldEmpty(frequencyKPIValuesEntity.getCurrentAchievingRate())) {
                frequencyKPIValuesEntity.setCurrentAchievingRate("0");
            }
        }
        //替换模板数据
        replaceAll(doc, frequencyKPIValuesList);
        //取出图表
        XWPFChart chart = doc.getCharts().get(0);
        //根据属性第一列名称切换数据类型
        CTChart ctChart = chart.getCTChart();
        CTPlotArea plotArea = ctChart.getPlotArea();
        XWPFChart chart2 = document.createChart(16 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
        chart2.setWorkbook(chart.getWorkbook());
        //放入更新完的图形
        chart2.getCTChart().setPlotArea(plotArea);
        //说明
        chart2.getCTChart().setLegend(ctChart.getLegend());
        doc.close();
    }
  	/**
     * @Description: 替换段落和表格中
     */
    public static void replaceAll(XWPFDocument doc, List<FrequencyKPIValuesEntity> frequencyKPIValuesList) throws FileNotFoundException {
        // 处理图表数据,柱状图、折线图、饼图啊之类的
        doCharts(doc, frequencyKPIValuesList);
    }
 	/**
     * 处理图表
     */
    public static void doCharts(XWPFDocument doc, List<FrequencyKPIValuesEntity> frequencyKPIValuesList) throws FileNotFoundException {
        // 标题
        List<String> titleArr = new ArrayList<String>();
        titleArr.add("title");
        titleArr.add("达成率");
        titleArr.add("目标值");
        titleArr.add("实际值");
        // 字段名
        List<String> fldNameArr = new ArrayList<String>();
        fldNameArr.add("item1");
        fldNameArr.add("item2");
        fldNameArr.add("item3");
        fldNameArr.add("item4");

        // 数据集合
        List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();

        // 第一行数据
        Map<String, String> base1 = new HashMap<String, String>();
        for (int i = 0; i < frequencyKPIValuesList.size(); i++) {
            if (frequencyKPIValuesList.get(i).getCurrentKPIActualValue() != null) {
                base1 = new HashMap<>();
                base1.put("item1", frequencyKPIValuesList.get(i).getIndexName());
                String rate = frequencyKPIValuesList.get(i).getCurrentAchievingRate();
                if (rate.contains("%")) {
                    rate = rate.replaceAll("%", "");
                }
                double currentAchievingRate = 0.0;
                try {
                    currentAchievingRate = Double.parseDouble(rate);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                base1.put("item2", currentAchievingRate + "");
                base1.put("item3", frequencyKPIValuesList.get(i).getCurrentKPITargetValue());
                base1.put("item4", frequencyKPIValuesList.get(i).getCurrentKPIActualValue());
                listItemsByType.add(base1);
            }

        }

        // 获取word模板中的所有图表元素,用数组存放
        List<POIXMLDocumentPart> chartsList = new ArrayList<POIXMLDocumentPart>();
        //动态刷新图表
        List<POIXMLDocumentPart> relations = doc.getRelations();
        for (POIXMLDocumentPart poixmlDocumentPart : relations) {
            // 如果是图表元素
            if (poixmlDocumentPart instanceof XWPFChart) {
                chartsList.add(poixmlDocumentPart);
            }
        }

        // 组合图(柱状图+折线图)
        POIXMLDocumentPart poixmlDocumentPart5 = chartsList.get(0);
        PoiWordTools.replaceCombinationCharts(poixmlDocumentPart5, titleArr, fldNameArr, listItemsByType);
    }
  /**
     * 调用替换柱状图、折线图组合数据
     *
     * @param poixmlDocumentPart 模板组合图数据
     * @param titleArr           标题
     * @param fldNameArr         字段名
     * @param listItemsByType    数据集合
     */
    public static void replaceCombinationCharts(POIXMLDocumentPart poixmlDocumentPart, List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
        XWPFChart chart = (XWPFChart) poixmlDocumentPart;
        chart.getCTChart();

        //根据属性第一列名称切换数据类型
        CTChart ctChart = chart.getCTChart();
        CTPlotArea plotArea = ctChart.getPlotArea();

        CTLegend ctLegend = ctChart.addNewLegend();
        ctLegend.addNewLegendPos().setVal(STLegendPos.B);
        ctLegend.addNewOverlay().setVal(false);


        CTBarChart barChart = plotArea.getBarChartArray(0);
        // 获取柱状图单位
        List<CTBarSer> barSerList = barChart.getSerList();
        //刷新内置excel数据
        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
        //刷新页面显示数据
        refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, titleArr, 1);


        CTLineChart lineChart = plotArea.getLineChartArray(0);
        // 获取折线图单位
        List<CTLineSer> lineSerList = lineChart.getSerList();
        //刷新内置excel数据
        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
        //刷新页面显示数据
        refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, titleArr, 2);
        ctChart.setPlotArea(plotArea);
    }
 /**
     * 刷新内置excel数据
     *
     * @param chart
     * @param dataList
     * @param fldNameArr
     * @param titleArr
     * @return
     */
    public static boolean refreshExcel(XWPFChart chart, List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr) {
        boolean result = true;
        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("Sheet1");
        //根据数据创建excel第一行标题行
        for (int i = 0; i < titleArr.size(); i++) {
            if (sheet.getRow(0) == null) {
                sheet.createRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
            } else {
                sheet.getRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
            }
        }
        //遍历数据行
        for (int i = 0; i < dataList.size(); i++) {
            //数据行
            Map<String, String> baseFormMap = dataList.get(i);
            //fldNameArr字段属性
            for (int j = 0; j < fldNameArr.size(); j++) {
                if (sheet.getRow(i + 1) == null) {
                    if (j == 0) {
                        try {
                            sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)) == null ? "" : baseFormMap.get(fldNameArr.get(j)));
                        } catch (Exception e) {
                            if (baseFormMap.get(fldNameArr.get(j)) == null) {
                                sheet.createRow(i + 1).createCell(j).setCellValue("");
                            } else {
                                sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)));
                            }
                        }
                    }
                } else {
                    double value = 0d;
                    if (isNumeric(baseFormMap.get(fldNameArr.get(j)))) {
                        BigDecimal b = new BigDecimal(baseFormMap.get(fldNameArr.get(j)));
                        value = b.doubleValue();
                    }
                    if (value == 0) {
                        sheet.getRow(i + 1).createCell(j);
                    } else {
                        sheet.getRow(i + 1).createCell(j).setCellValue(value);
                    }
                }
            }
        }
        // 更新嵌入的workbook
        POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
        OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
        try {
            wb.write(xlsOut);
            xlsOut.close();
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        } finally {
            if (wb != null) {
                try {
                    wb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    result = false;
                }
            }
        }
        return result;
    }
/**
     * 刷新折线图数据方法
     *
     * @param typeChart
     * @param serList
     * @param dataList
     * @param fldNameArr
     * @param position
     * @return
     */
    public static boolean refreshLineStrGraphContent(Object typeChart, List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr, int position) {

        boolean result = true;
        //更新数据区域
        for (int i = 0; i < serList.size(); i++) {
            //CTSerTx tx=null;
            CTAxDataSource cat = null;
            CTNumDataSource val = null;
            CTLineSer ser = ((CTLineChart) typeChart).getSerArray(i);

            ser.getTx().getStrRef().getStrCache().getPtList().get(0).setV(titleArr.get(i + position));
            cat = ser.getCat();
            // 获取图表的值
            val = ser.getVal();
            CTStrData strData = cat.getStrRef().getStrCache();
            CTNumData numData = val.getNumRef().getNumCache();
            strData.setPtArray((CTStrVal[]) null);
            numData.setPtArray((CTNumVal[]) null);
            long idx = 0;
            for (int j = 0; j < dataList.size(); j++) {
                //判断获取的值是否为空
                String value = "0";
                if (isNumeric(dataList.get(j).get(fldNameArr.get(i + position)))) {
                    value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
                }
                if (!"0".equals(value)) {
                    //序列值
                    CTNumVal numVal = numData.addNewPt();
                    numVal.setIdx(idx);
                    numVal.setV(value);
                }
                //序列名称
                CTStrVal sVal = strData.addNewPt();
                sVal.setIdx(idx);
                sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
                idx++;
            }
            numData.getPtCount().setVal(idx);
            strData.getPtCount().setVal(idx);


            //赋值横坐标数据区域
            String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString("Sheet1", true);
            cat.getStrRef().setF(axisDataRange);

            //数据区域
            String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position).formatAsString("Sheet1", true);
            val.getNumRef().setF(numDataRange);

        }
        return result;
    }
 /**
     * 刷新柱状图数据方法
     *
     * @param typeChart  柱状图
     * @param serList    柱状图单位
     * @param dataList   数据集合
     * @param fldNameArr 字段名
     * @param position   位置
     * @return
     */
    public static boolean refreshBarStrGraphContent(Object typeChart, List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr, int position) {

        boolean result = true;
        //更新数据区域
        for (int i = 0; i < serList.size(); i++) {
            //CTSerTx tx=null;
            CTAxDataSource cat = null;
            CTNumDataSource val = null;
            CTBarSer ser = ((CTBarChart) typeChart).getSerArray(i);
//            CTStrRef ctStrRef = ser.addNewTx().addNewStrRef();
            
			//Legend赋值
            ser.getTx().getStrRef().getStrCache().getPtList().get(0).setV(titleArr.get(i + position));
            cat = ser.getCat();
            // 获取图表的值
            val = ser.getVal();
            // strData.set
            CTStrData strData = cat.getStrRef().getStrCache();
            CTNumData numData = val.getNumRef().getNumCache();
            strData.setPtArray((CTStrVal[]) null);
            numData.setPtArray((CTNumVal[]) null);
            long idx = 0;
            BigDecimal bigDecimal = null;
            for (int j = 0; j < dataList.size(); j++) {
                //判断获取的值是否为空
                String value = "0";
                bigDecimal = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position)));
                if (bigDecimal != null) {
                    value = bigDecimal.toString();
                }
                if (!"0".equals(value)) {
                    //序列值
                    CTNumVal numVal = numData.addNewPt();
                    numVal.setIdx(idx);
                    numVal.setV(value);
                }
                //序列名称
                CTStrVal sVal = strData.addNewPt();
                sVal.setIdx(idx);
                sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
                idx++;
            }
            numData.getPtCount().setVal(idx);
            strData.getPtCount().setVal(idx);
            //赋值横坐标数据区域
            String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString("Sheet1", true);
            cat.getStrRef().setF(axisDataRange);
            //数据区域
            String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position).formatAsString("Sheet1", true);
            val.getNumRef().setF(numDataRange);
        }
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值