主頁 > 後端開發 > poi自動生成Ecxel表格和Chart圖表

poi自動生成Ecxel表格和Chart圖表

2020-09-11 14:42:47 後端開發

最近因為業務需求,需要做poi自動匯出Ecxel表格和Chart折線圖的功能,
所以我在網上找到了一篇關于poi生成Chart圖表的博客,代碼很詳細,但是缺少相關注釋說明,
想要將它改造成自己需要的樣子費了不少功夫,網上關于poi生成Chart圖比較詳細的博客又少,所以特此分享一下,

首先需要匯入jar包,這里提供兩種版本,4.1.1和4.1.2版本的都可以,具體如下:



<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>4.1.1</version>
</dependency>
<dependency>
        <groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>4.1.1</version>
</dependency>
<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-scratchpad</artifactId>
       <version>4.1.1</version>
</dependency>
<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-examples</artifactId>
       <version>4.1.1</version>
</dependency>
<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-excelant</artifactId>
       <version>4.1.1</version>
</dependency>
<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>ooxml-schemas</artifactId>
      <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/xdocreport -->
<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>xdocreport</artifactId>
    <version>1.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans -->
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>3.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.19</version>
</dependency>
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>

匯入jar包后,先來說下我想實作的功能:
在固定的模板中(看個人公司的模板是什么樣子的),外部只需要傳入引數,即可動態生成Excel表格和相關的Chart折線圖,
下面為我想要做出的效果圖:


由上圖可以看出來,我們只需要傳入相關的引數,即可自動生成對應數量的Sheet頁,并在Sheet頁中自動生成Excel表和相關的折線圖,
好了,下面直接上代碼:

首先根據模板初始化資料,同時這也是我的測驗類:

public static void main(String[] args) {
    String filePath = "E:\\programming\\備份資料\\NewChart.xlsx"; //檔案路徑
    List<String> sheetNameArr = new ArrayList<>(Arrays.asList("總體分析","承保")); //Sheet頁名稱
    ArrayList<String> titleArr = new ArrayList<>(Arrays.asList("月份","1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"));//表頭欄位
    NewTestCharUtil.setSheetNameArr(sheetNameArr);
    NewTestCharUtil.setTitleArr(titleArr);

    Map<String,List> dataMap = new HashMap<>();//資料集合
    List<BaseFormMap> dataList = new ArrayList<>(); //資料集合1
    BaseFormMap baseFormMap1 = new BaseFormMap();
    baseFormMap1.put("value1","2019年運維");
    baseFormMap1.put("value2",1245);
    baseFormMap1.put("value3",1908);
    baseFormMap1.put("value4",345);
    baseFormMap1.put("value5",3456);
    baseFormMap1.put("value6",167);
    baseFormMap1.put("value7",856);
    baseFormMap1.put("value8",2345);
    baseFormMap1.put("value9",453);
    baseFormMap1.put("value10",2343);
    baseFormMap1.put("value11",785);
    baseFormMap1.put("value12",723);
    baseFormMap1.put("value13",567);
    BaseFormMap baseFormMap2 = new BaseFormMap();
    baseFormMap2.put("value1","2020年運維");
    baseFormMap2.put("value2",4562);
    baseFormMap2.put("value3",1234);
    baseFormMap2.put("value4",543);
    baseFormMap2.put("value5",237);
    baseFormMap2.put("value6",628);
    baseFormMap2.put("value7",231);
    baseFormMap2.put("value8",894);
    baseFormMap2.put("value9",786);
    baseFormMap2.put("value10",0);
    baseFormMap2.put("value11",0);
    baseFormMap2.put("value12",0);
    baseFormMap2.put("value13",0);
    BaseFormMap baseFormMap3 = new BaseFormMap();
    baseFormMap3.put("value1","2020年開發");
    baseFormMap3.put("value2",234);
    baseFormMap3.put("value3",243);
    baseFormMap3.put("value4",562);
    baseFormMap3.put("value5",1278);
    baseFormMap3.put("value6",512);
    baseFormMap3.put("value7",675);
    baseFormMap3.put("value8",444);
    baseFormMap3.put("value9",121);
    baseFormMap3.put("value10",0);
    baseFormMap3.put("value11",0);
    baseFormMap3.put("value12",0);
    baseFormMap3.put("value13",0);
    dataList.add(baseFormMap1);
    dataList.add(baseFormMap2);
    dataList.add(baseFormMap3);

    List<BaseFormMap> dataList2 = new ArrayList<>(); //資料集合2
    BaseFormMap baseFormMap4 = new BaseFormMap();
    baseFormMap4.put("value1","2019年運維");
    baseFormMap4.put("value2",123);
    baseFormMap4.put("value3",2378);
    baseFormMap4.put("value4",5474);
    baseFormMap4.put("value5",6734);
    baseFormMap4.put("value6",223);
    baseFormMap4.put("value7",546);
    baseFormMap4.put("value8",123);
    baseFormMap4.put("value9",999);
    baseFormMap4.put("value10",234);
    baseFormMap4.put("value11",456);
    baseFormMap4.put("value12",234);
    baseFormMap4.put("value13",678);
    BaseFormMap baseFormMap5 = new BaseFormMap();
    baseFormMap5.put("value1","2020年運維");
    baseFormMap5.put("value2",123);
    baseFormMap5.put("value3",3453);
    baseFormMap5.put("value4",567);
    baseFormMap5.put("value5",345);
    baseFormMap5.put("value6",5478);
    baseFormMap5.put("value7",567);
    baseFormMap5.put("value8",343);
    baseFormMap5.put("value9",899);
    baseFormMap5.put("value10",1233);
    baseFormMap5.put("value11",0);
    baseFormMap5.put("value12",0);
    baseFormMap5.put("value13",2342);
    BaseFormMap baseFormMap6 = new BaseFormMap();
    baseFormMap6.put("value1","2020年開發");
    baseFormMap6.put("value2",678);
    baseFormMap6.put("value3",454);
    baseFormMap6.put("value4",123);
    baseFormMap6.put("value5",1278);
    baseFormMap6.put("value6",456);
    baseFormMap6.put("value7",893);
    baseFormMap6.put("value8",123);
    baseFormMap6.put("value9",6734);
    baseFormMap6.put("value10",0);
    baseFormMap6.put("value11",234);
    baseFormMap6.put("value12",0);
    baseFormMap6.put("value13",0);
    dataList2.add(baseFormMap4);
    dataList2.add(baseFormMap5);
    dataList2.add(baseFormMap6);

    dataMap.put("dataList",dataList);
    dataMap.put("dataList2",dataList2);
    NewTestCharUtil.setDataMap(dataMap);

    boolean result = NewTestCharUtil.createChart(filePath,true,"line",dataMap);
    System.out.println(result);
}

NewTestCharUtil是我創建的poi工具類,其中定義了兩個主要的方法,分別是創建Excel和創建Chart圖的方法,如下:

public class NewTestCharUtil {
    private static Map<String,List> dataMap; //用于存放資料集
    private static List<String> sheetNameArr; //用于存放Sheet頁名字
    private static List<String> titleArr; //用于存放Excel表頭欄位

    /**
     * 創建Excel資料表
     * @param workbook 作業簿物件
     * @param sheet Sheet頁物件
     * @param sheetName Sheet頁名稱
     * @param fldNameArr 欄位名
     * @param dataList 資料集合
     * @param titleArr 標題集合
     * @return
     */
    public static boolean createExcel(XSSFWorkbook workbook,
                                      XSSFSheet sheet,
                                      String sheetName,
                                      List<String> fldNameArr,
                                      List<BaseFormMap> dataList,
                                      List<String> titleArr){
        //第一行標題樣式
        XSSFCellStyle title1Style = workbook.createCellStyle();
        title1Style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex()); //單元格填充色(藍色)
        title1Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //填充圖案
        title1Style.setAlignment(HorizontalAlignment.CENTER); //水平對齊方式(居中)

        //第二行標題樣式
        XSSFCellStyle title2Style = workbook.createCellStyle();
        title2Style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex()); //單元格填充色(藍色)
        title2Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //填充圖案
        title2Style.setBorderBottom(BorderStyle.THIN); //下邊框
        title2Style.setBorderTop(BorderStyle.THIN); //上邊框
        title2Style.setBorderLeft(BorderStyle.THIN); //左邊框
        title2Style.setBorderRight(BorderStyle.THIN); //右邊框
        title2Style.setAlignment(HorizontalAlignment.CENTER); //水平對齊方式(居中)

        //資料行單元格樣式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
        cellStyle.setBorderTop(BorderStyle.THIN); //上邊框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左邊框
        cellStyle.setBorderRight(BorderStyle.THIN); //右邊框
        cellStyle.setAlignment(HorizontalAlignment.CENTER); //水平對齊方式(居中)

        //資料行第一個單元格樣式
        XSSFCellStyle cell1Style = workbook.createCellStyle();
        cell1Style.setBorderBottom(BorderStyle.THIN); //下邊框
        cell1Style.setBorderTop(BorderStyle.THIN); //上邊框
        cell1Style.setBorderLeft(BorderStyle.THIN); //左邊框
        cell1Style.setBorderRight(BorderStyle.THIN); //右邊框
        cell1Style.setAlignment(HorizontalAlignment.CENTER); //水平對齊方式(居中)

        //列寬自適應
        for (int i=1; i<fldNameArr.size(); i++){
            sheet.autoSizeColumn(i,true);
        }
        //設定第一列單元格寬度
        sheet.setColumnWidth(0,sheet.getColumnWidth(0)*25/10);
        //創建第一行
        XSSFRow tableTitleNameRow = sheet.createRow(0);
        XSSFCell tableTitleName = tableTitleNameRow.createCell(0);
        tableTitleName.setCellValue(sheetName); //第一行標題單元格賦值
        //合并第一行單元格
        CellRangeAddress cra = new CellRangeAddress(0,0,0,fldNameArr.size()-1);
        sheet.addMergedRegion(cra);
        //對合并后的單元格進行樣式設定
        RegionUtil.setBorderBottom(BorderStyle.THIN,cra,sheet);
        RegionUtil.setBorderTop(BorderStyle.THIN,cra,sheet);
        RegionUtil.setBorderLeft(BorderStyle.THIN,cra,sheet);
        RegionUtil.setBorderRight(BorderStyle.THIN,cra,sheet);
        //對合并后的單元格進行居中
        sheet.getRow(0).getCell(0).setCellStyle(title1Style);

        XSSFRow tableTitleRow = sheet.createRow(1); //創建第二行
        //遍歷標題集合
        for(int i=0; i<titleArr.size(); i++){
            tableTitleRow.createCell(i).setCellValue((String) titleArr.get(i)); //第二行標題賦值
            tableTitleRow.getCell(i).setCellStyle(title2Style); //第二行標題設定樣式
        }

        int rowIndex = 2; //資料行計數器(從第三行開始創建)
        //遍歷創建資料行
        for(BaseFormMap dataMap:dataList){
            XSSFRow row = sheet.createRow(rowIndex);
            int cellIndex = 0; //單元格計數器
            //遍歷欄位名,將值從Map中取出
            for(String valueName:fldNameArr){
                if(cellIndex==0){
                    row.createCell(cellIndex).setCellValue((String)dataMap.get(valueName)); //對資料行單元格進行賦值
                }else{
                    row.createCell(cellIndex).setCellValue((int)dataMap.get(valueName)); //對資料行單元格進行賦值
                }
                row.getCell(cellIndex).setCellStyle(cellStyle); //資料單元格設定樣式
                cellIndex++; //單元格計數器
            }
            rowIndex++; //行計數器自增
        }
        return true;
    }

    /**
     * 創建Chart圖表
     * @param fullPath 檔案保存路徑
     * @param isCreated 是否創建Chart
     * @param type Chart圖型別
     * @param dataMap 資料集合
     * @return
     */
    public static boolean createChart(String fullPath,
                                      boolean isCreated,
                                      String type,
                                      Map<String,List> dataMap){
        //定義作業簿物件
        XSSFWorkbook workbook = new XSSFWorkbook();
        //定義回傳值
        boolean result = false;
        //定義流物件
        FileOutputStream fos = null;
        try {
            //判斷資料量和sheet量是否相等
            if(dataMap.keySet().size()!=sheetNameArr.size()){
                System.out.println("dataMap資料量和sheet量不相等,無法創建!");
                return result;
            }

            //判斷全路徑是否為空
            if(fullPath!=null || !"".equals(fullPath)){
                //獲取需要創建的Excel型別
                String excelType = fullPath.substring(fullPath.lastIndexOf("."));
                if(!".xlsx".equals(excelType)){
                    System.out.println("需創建的檔案型別不是xlsx,創建失敗!");
                }
            }else {
                System.out.println("全路徑不能為空!");
                return false;
            }

            //用于接收dataMap集合的鍵集
            List<String> dataMapKeyArr = new ArrayList<>();
            //回圈遍歷dataMap的鍵集
            for(String key:dataMap.keySet()){
                dataMapKeyArr.add(key);
            }

            //dataMap的鍵集的計數器
            int mapKeyIndex = 0;
            //判斷是否創建Chart
            if(isCreated){
                //判斷Chart圖型別是否正確
                if("".equals(type) || null==type || !"line".equals(type)){
                    System.out.println("Chart圖型別不正確,無法創建!");
                    return false;
                }

                //定義畫布物件
                XSSFDrawing drawing = null;
                //遍歷SheetNameArr,用于多次創建Sheet物件
                for (String sheetName:sheetNameArr){
                    //判斷Sheet頁名字是否為空
                    if(sheetName==null || "".equals(sheetName)){
                        System.out.println("Sheet頁名字不能為空!");
                        return false;
                    }

                    //創建資料集合
                    List<BaseFormMap> dataList = new ArrayList<>();
                    dataList = dataMap.get(dataMapKeyArr.get(mapKeyIndex));
                    mapKeyIndex++; //鍵集計數器自增

                    //獲取BaseFormMap的鍵集
                    List<String> fldNameArr = new ArrayList<>();
                    if(fldNameArr.size()==0){
                        BaseFormMap baseFormMap = dataList.get(0);
                        for (Object key: baseFormMap.keySet()){
                            fldNameArr.add((String) key);
                        }
                    }

                    //創建Sheet物件
                    XSSFSheet sheet = workbook.createSheet(sheetName);
                    //創建Excel表格
                    result = createExcel(workbook, sheet, sheetName, fldNameArr, dataList, titleArr);
                    if(!result){
                        System.out.println("Excel創建失敗!");
                        return result;
                    }

                    //創建一個畫布
                    drawing = sheet.createDrawingPatriarch();
                    //前四個引數是畫布位置偏移量引數,后四個引數是畫布大小引數(col1:畫布左上角位置;row1:從哪行開始創建畫布;col2:畫布寬度;row2:畫布高度)
                    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, dataMap.size()+4, (dataList.size()-1)*6, 27);
                    //創建一個Chart物件
                    XSSFChart chart = drawing.createChart(anchor);
                    //創建一個CTChar物件
                    CTChart ctChart = chart.getCTChart();
                    //創建繪圖區
                    CTPlotArea ctPlotArea = ctChart.getPlotArea();

                    //判斷需要創建的Chart圖型別
                    if("line".equals(type)){
                        //創建折線圖
                        CTLineChart ctLineChart = ctPlotArea.addNewLineChart();
                        CTBoolean ctBoolean = ctLineChart.addNewVaryColors();
                        ctLineChart.addNewGrouping().setVal(STGrouping.STANDARD); //STANDARD標準模式/STACKED堆疊模式(不要使用STACKED堆疊模式)

                        //創建序列,并且設定選中區域
                        for (int i = 0; i < dataList.size(); i++) {
                            CTLineSer ctLineSer = ctLineChart.addNewSer();
                            CTSerTx ctSerTx = ctLineSer.addNewTx();
                            //圖例區
                            CTStrRef ctStrRef = ctSerTx.addNewStrRef();
                            //引數1:從哪行開始獲取資料   引數2:獲取到哪行結束    引數3:從哪個單元格開始獲取資料   引數4:獲取到哪個單元格結束
                            String legendDataRange = new CellRangeAddress(i+2,i+2, 0, 0).formatAsString(sheetName, true);
                            ctStrRef.setF(legendDataRange);
                            ctStrRef.setF(legendDataRange);
                            ctLineSer.addNewIdx().setVal(i);

                            //橫坐標區
                            CTAxDataSource cttAxDataSource = ctLineSer.addNewCat();
                            ctStrRef = cttAxDataSource.addNewStrRef();
                            //引數1:從哪行開始獲取資料   引數2:獲取到哪行結束    引數3:從哪個單元格開始獲取資料   引數4:獲取到哪個單元格結束
                            String axisDataRange = new CellRangeAddress(1, 1, 1, dataList.get(i).values().size()).formatAsString(sheetName, true);
                            ctStrRef.setF(axisDataRange);

                            //資料區域
                            CTNumDataSource ctNumDataSource = ctLineSer.addNewVal();
                            CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
                            //引數1:從哪行開始獲取資料   引數2:獲取到哪行結束    引數3:從哪個單元格開始獲取資料   引數4:獲取到哪個單元格結束
                            String numDataRange = new CellRangeAddress(i+2, i+2, 1, dataList.get(i).values().size()).formatAsString(sheetName, true);
                            ctNumRef.setF(numDataRange);

                            //設定標簽格式
                            ctBoolean.setVal(false);
                            CTDLbls newDLbls = ctLineSer.addNewDLbls();
                            newDLbls.setShowLegendKey(ctBoolean);//折線節點上是否顯示圖例
                            ctBoolean.setVal(true);
                            newDLbls.setShowVal(ctBoolean);//折線節點上是否顯示值

                            ctBoolean.setVal(false);
                            newDLbls.setShowCatName(ctBoolean);
                            newDLbls.setShowSerName(ctBoolean);
                            //newDLbls.setShowPercent(ctBoolean);
                            //newDLbls.setShowBubbleSize(ctBoolean);
                            //newDLbls.setShowLeaderLines(ctBoolean);

                            //是否開啟平滑曲線
                            CTBoolean addNewSmooth = ctLineSer.addNewSmooth();
                            addNewSmooth.setVal(false);

                            //是否是堆積曲線
                            CTMarker addNewMarker = ctLineSer.addNewMarker();
                            CTMarkerStyle addNewSymbol = addNewMarker.addNewSymbol();
                            //設定節點形狀:CIRCLE:圓形節點 DASH:破折號節點(短橫線)DIAMOND:菱形節點 DOT:短橫線節點(很短)PICTURE:圖表為圖片 PLUS:+節點 SQUARE:方塊節點 STAR:*形節點 TRIANGLE:三角形節點 X:X形節點
                            addNewSymbol.setVal(STMarkerStyle.NONE);
                        }
                        //telling the BarChart that it has axes and giving them Ids
                        ctLineChart.addNewAxId().setVal(123456);
                        ctLineChart.addNewAxId().setVal(123458);

                        //設定X軸
                        CTCatAx ctCatAx = ctPlotArea.addNewCatAx();
                        ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
                        CTScaling ctScaling = ctCatAx.addNewScaling();
                        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);//MAX_MIN:X軸從左到右由大到小(會導致Y軸顯示在右側,影像左右反轉)   MIN_MAX:正常顯示
                        ctCatAx.addNewAxPos().setVal(STAxPos.L);
                        ctCatAx.addNewCrossAx().setVal(123458); //id of the val axis
                        ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); //HIGH:X軸坐標顯示在頂部  LOW:X軸坐標正常顯示  NEXT_TO:X軸坐標正常顯示

                        //設定Y軸
                        CTValAx ctValAx = ctPlotArea.addNewValAx();
                        ctValAx.addNewAxId().setVal(123458); //id of the val axis
                        ctScaling = ctValAx.addNewScaling();
                        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX); //MAX_MIN:Y軸坐標從上到下由小到大(會導致X軸顯示在頂部,影像上下反轉) MIN_MAX:正常顯示
                        ctValAx.addNewAxPos().setVal(STAxPos.B);
                        ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
                        ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); //HIGH:Y軸刻度左側顯示,坐標值右側顯示  LOW:Y軸坐標正常顯示  NEXT_TO:Y軸坐標正常顯示

                        ctValAx.addNewDelete().setVal(false);//是否隱藏Y軸
                        ctCatAx.addNewDelete().setVal(false);//是否隱藏X軸

                        //legend圖注
                        CTLegend ctLegend = ctChart.addNewLegend();
                        ctLegend.addNewLegendPos().setVal(STLegendPos.B);
                        ctLegend.addNewOverlay().setVal(false);
                    }
                }
            }else{
                //遍歷SheetNameArr,用于多次創建Sheet物件
                for (String sheetName:sheetNameArr){
                    //創建Sheet物件
                    XSSFSheet sheet = workbook.createSheet(sheetName);
                    List<BaseFormMap> dataList = new ArrayList<>();
                    dataList = dataMap.get(dataMapKeyArr.get(mapKeyIndex));
                    //獲取BaseFormMap的鍵集
                    List<String> fldNameArr = new ArrayList<>();
                    if(fldNameArr.size()==0){
                        BaseFormMap baseFormMap = dataList.get(0);
                        for (Object key: baseFormMap.keySet()){
                            fldNameArr.add((String) key);
                        }
                    }
                    //創建Excel表格
                    result = createExcel(workbook, sheet, sheetName, fldNameArr, dataList, titleArr);
                    if(!result){
                        System.out.println("Excel創建失敗!");
                        return result;
                    }
                    mapKeyIndex++; //鍵集計數器自增
                }
            }

            fos = new FileOutputStream(fullPath);
            workbook.write(fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null!=fos){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return  result;
    }


    public static Map<String, List> getDataMap() {return dataMap;}
    public static void setDataMap(Map<String, List> dataMap) {NewTestCharUtil.dataMap = dataMap;}
    public static List<String> getSheetNameArr() {return sheetNameArr;}
    public static void setSheetNameArr(List<String> sheetNameArr) {NewTestCharUtil.sheetNameArr = sheetNameArr;}
    public static List<String> getTitleArr() {return titleArr;}
    public static void setTitleArr(List<String> titleArr) {NewTestCharUtil.titleArr = titleArr;}
}
package com.java.pojo;

import java.util.HashMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

public class BaseFormMap<K,V> extends TreeMap<K,V> {
}

以上代碼運行之后,就能創建出本博客一開始想要實作的效果,
因為我暫時只實作了一個折線圖,所以目前只能圖表型別只能傳"line",后期等我實作了其他形式的chart圖,我再回來補充,

在使用的時候,有幾個需要注意的點:
1.`STGrouping.STANDAR`用于設定Chart圖的模式,分為標準模式和堆疊模式,折線圖創建的時必須用標準模式,使用堆疊模式會使折線出現偏差;
2.`addNewSmooth.setVal(false);`設定為ture可以讓原本有棱有角的折線圖,變得如牛奶般絲滑....
3.`STMarkerStyle.NONE`是折線圖中折點的形狀,具體的可以參照上面注釋中的值設定(誰讓我閑得慌把所有折點形狀都試了一遍呢~)
4.`createChart()`方法中傳入的isCreated,是創建chart圖的開關,傳入false可以只創建Excel,不創建chart,傳入ture可以同時創建;
5.最重要的一點:chart圖創建時,是根據我們提供的選值范圍坐標,從之前創建的Excel圖選定需要遍歷的資料范圍,然后自動建圖,建圖正確與否、數值獲取正確與否的關鍵,在于我們提供的選值范圍坐標!


有興趣的還可以再加上一段根據路徑中檔案后綴,自動創建對應型別Excel檔案的代碼,這個比較簡單,我就不贅述了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/5957.html

標籤:Java

上一篇:@NotNull @NotBlank @NotEmpty

下一篇:Java例外

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more