文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【JAVA - POI 合集】之 POI 操作word 图表,柱状图,折线图,雷达图,条形图 poi4.1.2

2023-09-12 15:30

关注

        关于poi 操作word 的吐槽: 山路崎岖, 一言难尽啊!!!

        原本项目中的poi 版本是3.17的版本,但是3.17对于在word 中操作图表是有问题的。所以对项目的jar 包进行了升级,升级到了4.1.2。 要求JDK  1.8 以上. 现在用8以下的项目基本上也很少了。话不多说, 进入主题:

poi版本:4.1.2 

涉及到的所有jar 包:

commons-compress-1.18.jar
commons-collections4-4.1.jar
poi-4.1.2.jar
poi-examples-4.1.2.jar
poi-excelant-4.1.2.jar
poi-ooxml-4.1.2.jar
poi-ooxml-schemas-4.1.2.jar
poi-scratchpad-4.1.2.jar
ooxml-schemas-1.4.jar
xmlbeans-3.1.0.jar

 

POI 可以操作word 中的图表类型基本上 跟echarts 差不多。 包含 柱状图(条形图),折线图,雷达图,柱状+折现的组合图,饼图等。 这次就主要说几个常用的图。

POI 操作word 图表的方式分为两种(我接触到的):

第一种:创建一个word 模板,在word 文档中事先插入柱状图,或者其他要用到的图表。通过将数据刷到图表对应的内置EXCEL 表格中,将数据展示在图表中。

第二种:动态插入图表,在word 文档中事先插入对应的标记 exp ${barChart_1} 找到该标记,将标记替换为空,并将后台生成的图表插入到word 文档中。

3.1 两种方式优缺点对比

第一种优点:图表的格式可以很好的控制,坐标轴,,数据标签,误差线,网格线,图例等都可以事先在模板中设置好,最终只需要关心数据的问题就可以了。 缺点:如果有动态插入,且图表数量不固定的情况下,就无法事先在模板中创建对应的图表进行展示。

第二种优点:可以做到动态插入,只需要事先在指定的位置中打入标记。 如果标记也不固定可以在插入图表前,先对word 中段落进行遍历,将标记${barChart_1}插入到指定的位置,插入的图表的时候在将插入的标记替换为图表。缺点:样式不容易控制,生成的图表和在word 中直接创建的图表略有差异。基础的插入缺失很多属性, 需要将属性分别设置到图表中。还存在部分属性不生效的问题。(有大神解决的话,本人虚心求教)

3.2 代码展示

下方代码是操作固定模板中事先创建好的图表

tips:(1)在word文档中插入标记的时候需要先在notepad++ 这类纯文本编辑器中将标记写好,然后复制到word 文档中,否则这个标记可能会被word 拆分成多个词,无法进行匹配。(2)输入图表的时候,尽量在输入法中一次性将输入完成,不要分开多次插入。如图所示:

JAVA poi 动态插入图表, 一些属性的设置

设置图例的位置

        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.BOTTOM); // 图例位置:上下左右

设置柱状图为条形图

        XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, xAxis, yAxis);
barChart.setBarDirection(BarDirection.COL); // COL 为条形图  BAR 为柱状图

设置X轴的文字一直在最下方, 不会因为负数的原因导致图形和X轴的标签文字重合

        XDDFCategoryAxis xAxisLine = chartLine.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置
        xAxisLine.setTickLabelPosition(AxisTickLabelPosition.LOW); // 设置X轴的文字一直在最下方

展示数据标签 和调整数据标签的位置

CTPlotArea plotArea = chartLine.getCTChart().getPlotArea();
for (CTLineSer ser : plotArea.getLineChartArray(0).getSerList()) {
        CTDLbls ctdLbls = ser.addNewDLbls();
        ctdLbls.addNewShowVal().setVal(true);// 是否展示数值
        ctdLbls.addNewDLblPos().setVal(STDLblPos.IN_END);//数据标签位置
}

设置折线图的线条样式和标记点样式

        lineSeries.setSmooth(false); // 线条样式:true平滑曲线,false折线
        lineSeries.setMarkerStyle(MarkerStyle.NONE); // 标记点样式

设置数据标签的格式

        barSeries.getValuesData().setFormatCode("##0.0"); // 保留一位小数

如果有多条折线图或者柱状图, 调整柱状图的颜色

private static void solidFillSeries(CTBarSer ser, int i) {
        List colorArr = new ArrayList<>();
        colorArr.add(new Integer[]{127, 100, 162});
        colorArr.add(new Integer[]{155,187,89});
        colorArr.add(new Integer[]{192,80,77});
        colorArr.add(new Integer[]{79,128,189});
        Integer[] color = colorArr.get(i);
        CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
        Color col1 = new Color(color[0],color[1],color[2]);
        rgb.setVal(new byte[]{(byte) col1.getRed(), (byte) col1.getGreen(), (byte)         col1.getBlue()});
        CTSolidColorFillProperties fillProp =         CTSolidColorFillProperties.Factory.newInstance();
        fillProp.setSrgbClr(rgb);
        CTShapeProperties ctShapeProperties = CTShapeProperties.Factory.newInstance();
        ctShapeProperties.setSolidFill(fillProp);
        ser.setSpPr(ctShapeProperties);
}

 下方代码是操作固定模板中事先创建号的图表:

public  static void charGeneration(XWPFDocument doc, String tit, List dataArray){     if (dataArray != null && dataArray.size() > 0) {        List relations = doc.getRelations(); // 获取模版中所有的表格模版            int index=0;            for (POIXMLDocumentPart poixmlDocumentPart : relations)                if (poixmlDocumentPart instanceof XWPFChart) { //判断是不是图表类型                    XWPFChart chart = (XWPFChart) poixmlDocumentPart;                    String charType = ""; // charType 1 普通图表柱状图  2 折线图单条和2条 3 雷达图 4 多条折线图                    XDDFTitle xddfTitletitle = chart.getTitle();                    XDDFTextBody body = xddfTitletitle.getBody();                    CTTextBody xmlObject = body.getXmlObject();                    String tt = xmlObject.toString(); //图表的                    List keyList = new ArrayList<>();                    List keyListTemp = new ArrayList<>();                    List titleArr = new ArrayList<>();                    //根据属性第一列名称切换数据类型                    CTChart ctChart = null;                    CTPlotArea plotArea = null;                    if (tt.contains(tit) && tit.equals("图表1")){//折线图                        //刷新内置excel数据                        charType = "2"; // charType 1 普通图表柱状图  2 折线图 3 雷达图                        keyList.add("nd");                        keyList.add("value1");                        keyList.add("value2");                        titleArr.add("");                        titleArr.add("餐补");                        titleArr.add("交通补贴");                        ctChart = chart.getCTChart();                        plotArea = ctChart.getPlotArea();                    }else if (tt.contains(tit) && tit.contains("图表2")) {                        charType = "1";                        keyList.add("ssnd");                        keyList.add("value1");                        keyList.add("value2");                        titleArr.add("");                        titleArr.add("收入");                        titleArr.add("支出");                        ctChart = chart.getCTChart();                        plotArea = ctChart.getPlotArea();                    }                    if (StringUtils.isNotEmpty(charType)) {                                                refreshExcel(chart, dataArray,keyList,titleArr);                        //刷新页面显示数                        List newKey = new ArrayList<>(); //之所以要new 一个新的对象,直接赋值,只是赋值了引用地址                    if (charType.equals("1")) {CTBarChart barChart = plotArea.getBarChartArray(0);List  serList = barChart.getSerList();int position = 1;refreshNumGraphContent(barChart, serList,                 dataArray,keyList,titleArr);                        }                        if (charType.equals("2")) {CTLineChart lineChart = plotArea.getLineChartArray(0);List  serList = lineChart.getSerList();int position = 1;refreshLineStrGraphContent(lineChart, serList, dataArray,keyList,titleArr);                        }                        break;                    }    }}    public static boolean refreshLineStrGraphContent(CTLineChart lineChart,                         List serList, List dataList,List keyList,                         List titleList) {        boolean result = true;        int position = 1;        if (dataList.size() < 1) {            return false;        }        List tList = new ArrayList();        int keyIndex=1;        //更新数据区域        for (int i = 0; i < serList.size(); i++) {            CTAxDataSource cat = null;            CTNumDataSource val = null;            CTLineSer ser =lineChart.getSerArray(i);            cat = ser.getCat();            // 获取图表的值            val = ser.getVal();            CTSerTx tx = ser.getTx();            CTStrRef strRefH = cat.getStrRef();            CTStrData strCacheH = strRefH.getStrCache();            CTStrData strCache = tx.getStrRef().getStrCache();            CTNumData numData = val.getNumRef().getNumCache();            strCache.setPtArray((CTStrVal[]) null); // unset old axis text            strCacheH.setPtArray((CTStrVal[]) null); // unset old axis text            numData.setPtArray((CTNumVal[]) null); // unset old values            // set model            int idx = 0;            CTStrVal strVal1 = strCache.addNewPt();//序列名称            if (titleList.size() == 2) {                strVal1.setIdx(i);                strVal1.setV(titleList.get(1));            }else{                strVal1.setIdx(i);                strVal1.setV(titleList.get(i+1));            }            for (int j = 0; j < dataList.size(); j++) {                CTStrVal strVal = strCacheH.addNewPt();//序列名称                strVal.setIdx(idx);                strVal.setV(dataList.get(j).getString(keyList.get(0)));                for (int i1 = 0; i1 < keyList.size(); i1++) {                    String value = "0";                    if (i1 == 0) {                        if (idx>0){continue;                        }else{                        }                    }else{                        if (StringUtil.checkChinese(dataList.get(j).getString(keyList.get(keyIndex)))){continue;                        }                        String zb = "0";                        if (dataList.get(j).get(keyList.get(keyIndex))!=null && !dataList.get(j).getString(keyList.get(keyIndex)).trim().equals("--")){zb = dataList.get(j).getString(keyList.get(keyIndex));if(StringUtil.isNullString(zb)){    zb = "0";}if (zb.indexOf("%")>0){    BigDecimal b = new BigDecimal(100);    zb = zb.replace("%","");    zb = new BigDecimal(zb).divide(b).setScale(4, BigDecimal.ROUND_HALF_UP).toString();}                        }                        if(new BigDecimal(zb)!=null){value=new BigDecimal(zb).toString();                        }                        if(!"0".equals(value)){CTNumVal numVal = numData.addNewPt();//序列值numVal.setIdx(idx);numVal.setV(value);                        }                        idx++;                        break;                    }                }            }            numData.getPtCount().setVal(idx);            if (i==0){                strCache.getPtCount().setVal(idx);                String legendDataRange = new CellRangeAddress(0, 0, 1, idx + 1)                        .formatAsString("Sheet1", true);                tx.getStrRef().setF(legendDataRange);                //赋值横坐标数据区域                String axDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)                        .formatAsString("Sheet1", true);                cat.getStrRef().setF(axDataRange);            }            //数据区域            String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)                    .formatAsString("Sheet1", false);            val.getNumRef().setF(numDataRange);            // 设置系列生成方向            if (keyList.size() != 2) {                keyIndex++;            }        }        return result;    }    public static boolean refreshExcel(XWPFChart chart,           List dataList,List keyList,List titleArr) {        boolean result = true;        Workbook wb = new XSSFWorkbook();        Sheet sheet = wb.createSheet("Sheet1");        //根据数据创建excel第一行行        sheet.createRow(0).createCell(0).setCellValue("");        for (int i = 1; i < titleArr.size(); i++) {            sheet.getRow(0).createCell(i).setCellValue(titleArr.get(i)==null?"":titleArr.get(i));        }        //遍历数据行        for (int i = 0; i < dataList.size(); i++) {            JSONObject baseFormMap = dataList.get(i);//数据行            //fldNameArr字段属性            for (int j = 0; j < keyList.size(); j++) {                if(sheet.getRow(i+1)==null){                    if(j==0){                        try {sheet.createRow(i+1).createCell(j).setCellValue(baseFormMap.getString(keyList.get(j))==null?"":baseFormMap.getString(keyList.get(j)));                        } catch (Exception e) {if(baseFormMap.get(keyList.get(i))==null){    sheet.createRow(i+1).createCell(j).setCellValue("");}else{    sheet.createRow(i+1).createCell(j).setCellValue(baseFormMap.getString(keyList.get(j)));}                        }                    }                }else{                    String dvl = baseFormMap.getString(keyList.get(j));                    if (StringUtil.checkChinese(dvl)) {                        continue;                    }                    double value=0d;                    String zb = "0";                    if (baseFormMap.getString(keyList.get(j))!=null && !baseFormMap.getString(keyList.get(j)).trim().equals("--")){                        zb = baseFormMap.getString(keyList.get(j));                        if(StringUtil.isNullString(zb)){zb = "0";                        }                        if (zb.indexOf("%")>0){BigDecimal b = new BigDecimal(100);zb = zb.replace("%","");zb = new BigDecimal(zb).divide(b).setScale(4, BigDecimal.ROUND_UP).toString();                        }                    }                    if(new BigDecimal(zb)!=null){                        value=new BigDecimal(zb).doubleValue();                    }                    if(StringUtils.isEmpty(dvl)){                        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;    }

动态插入图表:

public static void insetChart(XWPFDocument document, List list) throws Exception {//根据数据的条数, 插入对应数量的标记boolean breakPoint = true; // 终止多层循环        // 1、创建word文档对象        List paragraphs = document.getParagraphs();        if (hxqyList.size() > 0) {            for (XWPFParagraph per : paragraphs) {                if (breakPoint) {                    List runs = per.getRuns();                    for (XWPFRun run : runs) {                        //获取文本的值                        String text = run.getText(0);                        if (StringUtils.isNotEmpty(text)) {if (text.contains("${hxqyChart_1}")) {    for (int i = 0; i < hxqySize; i++) {        run.addCarriageReturn();        XWPFRun run1 = per.createRun();        run1.setText("${hxqyChart_"+(i+2)+"}");        run1.addCarriageReturn();        run1.setFontFamily("宋体");        run1.setFontSize(14);        per.addRun(run1);    }    breakPoint=false;    break;}                        }                    }                }            }        }        for (JSONObject hxObject : hxqyList) {            int runIndex = 1;            for (XWPFParagraph per : paragraphs) {                List runs = per.getRuns();                for (XWPFRun run : runs) {                    //获取文本的值                    String text = run.getText(0);                    if (StringUtils.isNotEmpty(text)) {                        if (text.contains("hxqyChart")) {run.setText("1.2."+runIndex+hxObject.getString("nsrmc"), 0);per.setAlignment(ParagraphAlignment.LEFT);//对齐方式run.setText(hxObject.getString(""), 1);run.addBreak();String zcfzTitle = "柱状图";String zcfzTitle1 = "折线图";//插入柱状图insertBarchar(document, run,zcfzTitle,hxObject.getJSONArray("zcfzzk_zzt"));//插入折线图insertLineChart(document,run,zcfzTitle1,hxObject.getJSONArray("zcfzzk_zxt"));                     }                    }                }            }            runIndex++;        }        }private static void insertBarchar(XWPFDocument document, XWPFRun run, String title, JSONArray dataArray) throws Exception{        List dataObjList = new ArrayList<>();        if (dataArray != null && dataArray.size() > 0) {            dataObjList = JSONObject.parseArray(dataArray.toJSONString(), JSONObject.class);        }        // 2、创建chart图表对象,抛出异常        XWPFChart chart = document.createChart(run, (int)(14.5 * Units.EMU_PER_CENTIMETER), 9 * Units.EMU_PER_CENTIMETER);        chart.setChartTopMargin(1000L);        // 3、图表相关设置        chart.setTitleText(title); // 图表        chart.setTitleOverlay(false); // 图例是否覆盖        // 4、图例设置        XDDFChartLegend legend = chart.getOrAddLegend();        legend.setPosition(LegendPosition.BOTTOM); // 图例位置:上下左右        String[] xAxisData = new String[4];        Double[] yAxisData = new Double[4];        Double[] yAxisData1 = new Double[4];        for (int i = 0; i < dataObjList.size(); i++) {            if (title.equals("柱状图1")) { //双柱状图                xAxisData[i] = dataObjList.get(i).getString("ssnd");                yAxisData[i] = dataObjList.get(i).getDouble("value1");                yAxisData1[i] = dataObjList.get(i).getDouble("value2");            }else if (title.equals("柱状图2")) {//单柱状图                xAxisData[i] = dataObjList.get(i).getString("ssnd");                yAxisData[i] = dataObjList.get(i).getDouble("value1");            }        }        // 5、X轴(分类轴)相关设置        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置        XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(xAxisData); // 设置X轴数据        // 6、Y轴(值轴)相关设置        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT); // 创建Y轴,指定位置        yAxis.setCrossBetween(AxisCrossBetween.BETWEEN); // 设置图柱的位置:BETWEEN居中        // 7、创建柱状图对象        XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, xAxis, yAxis);        barChart.setBarDirection(BarDirection.COL); // 设置柱状图的方向:BAR横向,COL竖向,默认是BAR        if (title.equals("图表1")) {            XDDFNumericalDataSource yAxisSource = XDDFDataSourcesFactory.fromArray(yAxisData); // 设置Y轴数据            XDDFNumericalDataSource yAxisSource1 = XDDFDataSourcesFactory.fromArray(yAxisData1); // 设置Y轴数据            // 8、加载柱状图数据集            XDDFBarChartData.Series barSeries = (XDDFBarChartData.Series) barChart.addSeries(xAxisSource, yAxisSource);            XDDFBarChartData.Series barSeries2 = (XDDFBarChartData.Series) barChart.addSeries(xAxisSource, yAxisSource1);            barSeries.setTitle("收入",null);            barSeries2.setTitle("支出",null);            barSeries.getValuesData().setFormatCode("##0.00");            barSeries2.getValuesData().setFormatCode("##0.00");        }else{            XDDFNumericalDataSource yAxisSource = XDDFDataSourcesFactory.fromArray(yAxisData); // 设置Y轴数据            // 8、加载柱状图数据集            XDDFBarChartData.Series barSeries = (XDDFBarChartData.Series) barChart.addSeries(xAxisSource, yAxisSource);            barSeries.getValuesData().setFormatCode("##0.00");                       barSeries.setTitle("收入",null);                   }        CTPlotArea plotArea = chart.getCTChart().getPlotArea();        for (CTBarSer ser : plotArea.getBarChartArray(0).getSerList()) {            CTDLbls ctdLbls = ser.addNewDLbls();            ctdLbls.addNewShowCatName().setVal(false);// 是否展示对应x轴上的值(类型名称)            ctdLbls.addNewShowVal().setVal(true);// 是否展示数值            ctdLbls.addNewShowSerName().setVal(false);// 是否展示归属折线名称(系列名称)            ctdLbls.addNewShowLegendKey().setVal(false);// 是否展示图例(图例项标示)            ctdLbls.addNewDLblPos().setVal(STDLblPos.IN_END);        }        // 9、绘制柱状图        chart.plot(barChart);    }private static void insertLineChart(XWPFDocument document,XWPFRun run,String title,JSONArray dataArray) throws Exception{        List dataObjList = JSONObject.parseArray(dataArray.toJSONString(), JSONObject.class);        XWPFChart chartLine = document.createChart(run, (int)(14.5 * Units.EMU_PER_CENTIMETER),                9 * Units.EMU_PER_CENTIMETER);        chartLine.setChartTopMargin(1000L);        // 3、图表相关设置        chartLine.setTitleText(title); // 图表        chartLine.setTitleOverlay(false); // 图例是否覆盖        // 4、图例设置        XDDFChartLegend legendLine = chartLine.getOrAddLegend();        legendLine.setPosition(LegendPosition.BOTTOM); // 图例位置:上下左右        // 5、X轴(分类轴)相关设置        XDDFCategoryAxis xAxisLine = chartLine.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置        xAxisLine.setTickLabelPosition(AxisTickLabelPosition.LOW); // 设置X周的文字一直在最下方        String[] xAxisDataLine = new String[4];        Double[] yAxisDataLine_1 = new Double[4];        Double[] yAxisDataLine_2 = new Double[4];        for (int i = 0; i < dataObjList.size(); i++) {            xAxisDataLine[i] = dataObjList.get(i).getString("ssqj");            if (title.equals("图表1")) {                yAxisDataLine_1[i] = dataObjList.get(i).getDouble("value1");                yAxisDataLine_2[i] = dataObjList.get(i).getDouble("value2");            } else if (title.equals("图表2")) {                yAxisDataLine_1[i] = dataObjList.get(i).getDouble("bdl_1");            }        }        XDDFCategoryDataSource xAxisSourceLine = XDDFDataSourcesFactory.fromArray(xAxisDataLine); // 设置X轴数据        // 6、Y轴(值轴)相关设置        XDDFValueAxis yAxisLine = chartLine.createValueAxis(AxisPosition.LEFT); // 创建Y轴,指定位置        yAxisLine.setCrossBetween(AxisCrossBetween.BETWEEN); // 设置图柱的位置:BETWEEN居中        // 7、创建柱状图对象        XDDFLineChartData lineChart = (XDDFLineChartData) chartLine.createData(ChartTypes.LINE, xAxisLine, yAxisLine);        if (title.equals("图表1")) {//双折线图            XDDFNumericalDataSource yAxisSourceLine = XDDFDataSourcesFactory.fromArray(yAxisDataLine_1); // 设置Y轴数据            XDDFNumericalDataSource yAxisSourceLine2 = XDDFDataSourcesFactory.fromArray(yAxisDataLine_2); // 设置Y轴数据            // 8、加载柱状图数据集            XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineChart.addSeries(xAxisSourceLine, yAxisSourceLine);            lineSeries.setTitle("收入", null); // 图例            XDDFLineChartData.Series lineSeries2 = (XDDFLineChartData.Series) lineChart.addSeries(xAxisSourceLine, yAxisSourceLine2);            lineSeries2.setTitle("支出", null); // 图例            setLineSeriesStyle(lineSeries);            setLineSeriesStyle(lineSeries2);        }else{            XDDFNumericalDataSource yAxisSourceLine = XDDFDataSourcesFactory.fromArray(yAxisDataLine_1); // 设置Y轴数据            XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineChart.addSeries(xAxisSourceLine, yAxisSourceLine);                        lineSeries.setTitle("营业收入",null);                        setLineSeriesStyle(lineSeries);        }        CTPlotArea plotArea = chartLine.getCTChart().getPlotArea();        for (CTLineSer ser : plotArea.getLineChartArray(0).getSerList()) {            CTDLbls ctdLbls = ser.addNewDLbls();            ctdLbls.addNewShowCatName().setVal(false);// 是否展示对应x轴上的值(类型名称)            ctdLbls.addNewShowVal().setVal(true);// 是否展示数值            ctdLbls.addNewShowSerName().setVal(false);// 是否展示归属折线名称(系列名称)            ctdLbls.addNewShowLegendKey().setVal(false);// 是否展示图例(图例项标示)            ctdLbls.addNewDLblPos().setVal(STDLblPos.IN_END);//数据标签        }        // 9、绘制柱状图        chartLine.plot(lineChart);    }

来源地址:https://blog.csdn.net/baidu_29596947/article/details/120526139

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯