1.前言

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

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

2.准备工作

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

3.正文

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 动态插入图表, 一些属性的设置

1:设置图例的位置

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

2:设置柱状图为条形图

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

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

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

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

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);//数据标签位置
}

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

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

6:设置数据标签的格式

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

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

private static void solidFillSeries(CTBarSer ser, int i) {
        List<Integer[]> 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<JSONObject> dataArray){ if (dataArray != null && dataArray.size() > 0) {List<POIXMLDocumentPart> 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<String> keyList = new ArrayList<>();List<String> keyListTemp = new ArrayList<>();List<String> 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)) {/*** 每个word 中的图表都会对应一个内置的excel .用来存放表格的数据.* 所以需要像图表的数据先写入内置的excel 中*/refreshExcel(chart, dataArray,keyList,titleArr);//刷新页面显示数List<String> newKey = new ArrayList<>(); //之所以要new 一个新的对象,直接赋值,只是赋值了引用地址if (charType.equals("1")) {CTBarChart barChart = plotArea.getBarChartArray(0);List <CTBarSer> serList = barChart.getSerList();int position = 1;refreshNumGraphContent(barChart, serList,                 dataArray,keyList,titleArr);}if (charType.equals("2")) {CTLineChart lineChart = plotArea.getLineChartArray(0);List <CTLineSer> serList = lineChart.getSerList();int position = 1;refreshLineStrGraphContent(lineChart, serList, dataArray,keyList,titleArr);}break;}}}/*** 刷新折线图数据方法** @param typeChart* @param serList* @param dataList* @param position* @return*/public static boolean refreshLineStrGraphContent(CTLineChart lineChart,List<?> serList, List<JSONObject> dataList,List<String> keyList,List<String> titleList) {boolean result = true;int position = 1;if (dataList.size() < 1) {return false;}List<String> 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 textstrCacheH.setPtArray((CTStrVal[]) null); // unset old axis textnumData.setPtArray((CTNumVal[]) null); // unset old values// set modelint 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;}/*** 刷新数据* @param chart* @param dataList* @param titleArr* @param showtailArr* @param ispercentArr* @return*/public static boolean refreshExcel(XWPFChart chart,List<JSONObject> dataList,List<String> keyList,List<String> 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);}}}}// 更新嵌入的workbookPOIXMLDocumentPart 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<JSONObject> list) throws Exception {
//根据数据的条数, 插入对应数量的标记
boolean breakPoint = true; // 终止多层循环// 1、创建word文档对象List<XWPFParagraph> paragraphs = document.getParagraphs();if (hxqyList.size() > 0) {for (XWPFParagraph per : paragraphs) {if (breakPoint) {List<XWPFRun> 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<XWPFRun> 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<JSONObject> 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竖向,默认是BARif (title.equals("图表1")) {XDDFNumericalDataSource<Double> yAxisSource = XDDFDataSourcesFactory.fromArray(yAxisData); // 设置Y轴数据XDDFNumericalDataSource<Double> 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<Double> 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<JSONObject> 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<Double> yAxisSourceLine = XDDFDataSourcesFactory.fromArray(yAxisDataLine_1); // 设置Y轴数据XDDFNumericalDataSource<Double> 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<Double> 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);}

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

  1. 解决 Java poi 3.8 等版本 操作 word 插入 图片 不成功的问题

    解决 Java poi 3.8等版本操作word插入图片不成功的问题 问题: 最近有一个需求是将Excel中的数据转换到word中,其中包括了文字和图片, 在使用 poi 3.8 向word中写入图片 ...

  2. 只会温水煮青蛙,工作都找不到还不好好学这份16W字Java面试合集

    蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力.培训.出国.大公司的经历,还有很多很好的朋友.但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,可惜 ...

  3. 别再找借口了!找不到工作还不好好学一下这份16W字Java面试合集

    背景 前两天在朋友圈发了一条招人的感慨,关于大厂招人和小公司招人的区别. 大厂:有影响力,有钱,能够吸引了大量的应聘者.因此,也就有了筛选的资格,比如必须985名校毕业,必须35岁以下,不能5年3跳, ...

  4. 【Java 面试合集】接口以及抽象类

    接口以及抽象类 1. 概述 嗨,[Java 面试合集]又来了,今天给大家分享的内容是接口以及抽象类. 一看这个概念很多人都知道,但是方方面面的细节不一定知道哦,今天我们就从方方面面的细节来讲讲 2. ...

  5. JAVA毕设合集【20套系统项目】

    对于即将毕业的大学生来说,完成毕业设计是最后一关,该如何完成呢? 今天呢,给大家分享一个毕设系统项目合集 共有20套 简介目录: 1.新冠疫情统计系统 2.进销存管理系统 3.家教系统 4.饮食分享平 ...

  6. c#操作word图表(二)

    c#操作word图表(excel) 这一篇是对上一篇操作word类文章的补充,上一篇是通过Microsoft.Office.Interop.Graph插入图表,但样式稍差,这次是通过调用excel来插 ...

  7. c#操作word图表(一)

    c#操作word图表 前阵子接到了一个任务,需要实现一个功能,利用代码在word中插入图表并且插入数据,生成类似于柱状图,饼图,线条之类乱七八糟的东西,关于这个方面,不得不说网上的资料相对较少,多方查 ...

  8. Java操作Word图表

    一.POM <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artif ...

  9. 最全Java项目合集(附源码课件),可完美运行

    当今时代是飞速发展的信息时代.在各行各业中离不开信息处理,而有信息处理就离不开信息管理系统,这使得信息管理系统被广泛应用于各领域 其中系统设计是一个把软件需求转换成用软件系统表示的过程.通过对目标系统 ...

最新文章

  1. [C#反射]C#中的反射解析及使用.
  2. c# ifram 刷新父页面
  3. csu 1976: 搬运工小明
  4. Echart图表入门
  5. python中的any与all函数的区别
  6. 互联网医疗的前世今生与未来
  7. BZOJ2131免费的馅饼 DP+树状数组
  8. html js css如何关联_html+css +js 选项卡
  9. 基于java的餐饮管理系统_基于java的餐饮管理系统
  10. Android studio 实验过程中遇到的问题之android.support.v7.app.AppCompatActivity不能使用的解决办法
  11. 20172310 《程序设计与数据结构》实验二报告
  12. Yahoo Programming Contest 2019 E - Odd Subrectangles
  13. Java 将Excel转为XML
  14. Android CHM文件阅读器
  15. global 与 $GLOBALS用法
  16. 电大php考试,电大考试搜题神器免费
  17. 水生火热的互联网金融
  18. switch的使用细节
  19. 为什么要学习 Linux?
  20. 计算机硬件小论文,计算机硬件小论文

热门文章

  1. Matlab findcircle函数实现 霍夫变换——检测圆
  2. 趋势|人工智能疯狂洗脑,最聪明的钱已转向这16项技术
  3. 【科创人上海行】扶墙老师王福强:架构师创业要突破思维局限,技术人创业的三种模式,健康第一...
  4. 阿里推出又一款数据高效同步工具DataX,真香、真牛X!
  5. 北京大学计算机考研学费,北京大学研究生新生报到大部分不需备学费
  6. 七、彩色图像处理(MATLAB)
  7. 有意思的软件需求漫画
  8. 参考文献处理有bibtex转换到biber过程中出现的问题
  9. linux格式化扩展分区报错解决
  10. 沙发面料的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告