JAVA生成EXCEL圖表

跟據客戶的要求,須要開發一套包括圖形的報表,還須要導出WORDapp

圖表須要這樣:ide

                       

這樣:工具

   

這樣:ui

  

還有這樣:this

   

 

接下來是實現思路:spa

  以往用的最多的就是JFreechart,手上也有實現各類圖形的資源,可是領導說用它作的圖形太醜了, 因此沒什麼卵用。3d

  FusionCharts到是漂亮,可是沒有辦法實現上述圖表,客戶也不能接受替代方案,一樣沒什麼卵用excel

  而後就是百度ECharts,漂亮、功能強大、靈活性強(JS/HTML5實現,能夠隨意更改源碼), 可是有些功能不支待IE8, 仍是沒什麼卵用code

 

      想了不少方法,最後又回到了原點,客戶要生成Office, 就讓Office給咱們作,雖然Java對操做圖表尚未什麼好的方法,可是jacob是能夠操做宏,咱們經過宏實現全部圖表功能。orm

一、 製做Excel圖表模板
  製做圖表看起來簡單,可是作起來至關的慢,好在客戶提供一些相似圖表,我作了一些調整就能夠了  膜拜。。。。。

  還有就是網上一堆的製做圖表的教程,就不記錄了。

 

二、 經過POI填充數據到Excel

 1 /**
 2      * 經過填充excel 生成圖表
 3      * @param list 圖標數據
 4      * @param inFile 模板文件
 5      * @param outFile 輸出文件
 6      * @return
 7      * @throws Exception
 8      */
 9     public static void createChart(List<Map> list, String inFile,String outFile) {
10         if(list == null) list = new ArrayList();
11         
12         System.out.println("圖表個數" + list.size());
13         System.out.println("源文件路徑" + inFile);
14         System.out.println("圖表個數" + outFile);
15         
16         try {
17             // 讀取模板
18             FileInputStream is = new FileInputStream(inFile);
19             HSSFWorkbook wbs = new HSSFWorkbook(is);
20             
21             int sheetIndex;
22             HSSFSheet sheet; //sheet
23             int rowIndex;
24             HSSFRow row; //
25             int cellIndex;
26             HSSFCell cell; //
27             String value;
28             float fvalue;
29             String valStr = "^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$";
30             
31             List<Integer> sheetList = new ArrayList();
32             for(Map tempMap:list) {
33                 // 讀取工做表(data)
34                 sheetIndex = Integer.parseInt(tempMap.get("SHEETINDEX") + "");
35                 sheet = wbs.getSheetAt(sheetIndex-1);
36                 sheetList.add(sheetIndex);
37                 
38                 /*
39                  int i = 0;
40                  List<HSSFPictureData> pictures = wbs.getAllPictures();  
41                  for (HSSFPictureData picData : pictures) {
42                      String ext = picData.suggestFileExtension();
43                      byte[] data = picData.getData();
44                      System.out.println(data.length);
45                         
46                         
47                         //savePic(row, picData);
48                         /*
49                         String ext = picData.suggestFileExtension();
50 
51                         byte[] data = picData.getData();
52                         if (ext.equals("jpeg")) {
53                             FileOutputStream out = new FileOutputStream(
54                                     "D:\\Users\\Fancy1_Fan\\桌面\\work\\pict" + i + ".jpg");
55                             out.write(data);
56                             out.close();
57                         }
58                         if (ext.equals("png")) {
59                             FileOutputStream out = new FileOutputStream(
60                                     "D:\\Users\\Fancy1_Fan\\桌面\\work\\pict" + i + ".png");
61                             out.write(data);
62                             out.close();
63                         }*//*
64                     i++;
65                  }*/
66                 
67                 //添加行
68                 rowIndex = Integer.parseInt(tempMap.get("ROWINDEX") + "");
69                 row = sheet.getRow(rowIndex-1);
70                 if(row == null) row = sheet.createRow(rowIndex-1);
71                 
72                 //
73                 cellIndex = Integer.parseInt(tempMap.get("CELLINDEX") + "");
74                 cell = row.getCell(cellIndex-1);
75                 
76                 value = tempMap.get("DATAINFO") + "";
77                 if(value.matches(valStr)) {
78                     fvalue = Float.parseFloat(value);
79 
80                     cell.setCellValue(fvalue);
81                 } else {
82                     cell.setCellValue(value);
83                 }
84                 //cell.setCellValue(tempMap.get("DATAINFO") + ""); //數據列
85             }
86             for(int temp:sheetList) {
87                 sheet = wbs.getSheetAt(temp-1);
88                 sheet.setForceFormulaRecalculation(true);
89             }
90             
91             // 輸出文件
92             FileOutputStream os = new FileOutputStream(outFile);
93             wbs.write(os);
94             is.close();
95             os.close();
96         } catch (Exception e) {
97             e.printStackTrace();
98         }
99     }
操做EXCEL,填充數據

 

三、 生成宏

個人基本思路是把全部生成的圖片復至到一個指定Sheet, 而後Java代碼只要到這個Sheet裏獲取圖形

    Sheets("QPLJYFJWXSQK").Select
    ActiveSheet.ChartObjects("圖表 1").Activate
    ActiveChart.PlotArea.Select
    ActiveChart.ChartArea.Copy
    Sheets("CHART").Select
    Range("A41").Select
    ActiveSheet.Pictures.Paste.Select
    ActiveCell.FormulaR1C1 = "QPLJYFJWXSQK"
複製圖表生成圖形

 

    Sheets("QGJYFJLXSQK").Select
    Range("J13:S20").Select
    ' 複製位圖
    Selection.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
    Sheets("CHART").Select
    Range("AA1").Select
    '粘貼爲圖片(問題:複製的位圖自動添加邊框線,經過裁減的方式刪除邊框線)
    ActiveSheet.Paste
    Selection.ShapeRange.PictureFormat.Crop.PictureOffsetX = -1
    Selection.ShapeRange.PictureFormat.Crop.PictureOffsetY = -1
    Selection.Copy
    Range("A1").Select
    ActiveSheet.Pictures.Paste.Select
    ActiveCell.FormulaR1C1 = "QGJYFJLXSQK"
複製單元格生成圖形

只要會VBA 基本語法,其它的若是不會,能夠經過錄制宏獲得

 

四、  調用宏

  先提供工具類

  1 package com.wiseda.fc.utils;
  2 
  3 import com.jacob.activeX.ActiveXComponent;
  4 import com.jacob.com.ComThread;
  5 import com.jacob.com.Dispatch;
  6 import com.jacob.com.Variant;
  7 
  8 public class JacobExcelUtils {
  9     private static ActiveXComponent xl = null; //Excel對象(防止打開多個)
 10     private static Dispatch workbooks = null;  //工做簿對象
 11     private Dispatch workbook = null; //具體工做簿
 12     private Dispatch sheets = null;// 得到sheets集合對象
 13     private Dispatch currentSheet = null;// 當前sheet
 14     
 15     public ActiveXComponent getXl() {
 16         return xl;
 17     }
 18 
 19     public Dispatch getWorkbooks() {
 20         return workbooks;
 21     }
 22 
 23     public Dispatch getWorkbook() {
 24         return workbook;
 25     }
 26 
 27     /**
 28      * 打開excel文件
 29      * @param filepath 文件路徑名稱
 30      * @param visible  是否顯示打開
 31      * @param readonly 是否只讀方式打開
 32      */
 33     public void OpenExcel(String filepath, boolean visible, boolean readonly) {
 34         try {
 35             initComponents(); //清空原始變量
 36             ComThread.InitSTA();
 37             if(xl==null)
 38                 xl = new ActiveXComponent("Excel.Application"); //Excel對象
 39             xl.setProperty("Visible", new Variant(visible));//設置是否顯示打開excel
 40             if(workbooks==null)
 41                 workbooks = xl.getProperty("Workbooks").toDispatch(); //工做簿對象
 42             workbook = Dispatch.invoke(  //打開具體工做簿
 43                     workbooks,
 44                     "Open",
 45                     Dispatch.Method,
 46                     new Object[] { filepath, new Variant(false),
 47                             new Variant(readonly) },// 是否以只讀方式打開
 48                             new int[1]).toDispatch();
 49         } catch (Exception e) {
 50             e.printStackTrace();
 51             releaseSource();
 52         }
 53     }
 54     
 55     /**
 56      * 工做簿另存爲
 57      * @param filePath 另存爲的路徑
 58      */
 59     public void SaveAs(String filePath){
 60            Dispatch.invoke(workbook, "SaveAs", Dispatch.Method,
 61                                       new Object[] { filePath,
 62                                                new Variant(44) }, new int[1]);
 63       }
 64     
 65     /**
 66      * 關閉excel文檔
 67      * @param f 含義不明 (關閉是否保存?默認false)
 68      */
 69     public void CloseExcel(boolean f,boolean quitXl) {
 70         try {
 71             Dispatch.call(workbook, "Save");
 72             Dispatch.call(workbook, "Close", new Variant(f));
 73         } catch (Exception e) {
 74             e.printStackTrace();
 75         } finally {
 76             if(quitXl){
 77                 releaseSource();
 78             }
 79         }
 80     }
 81     
 82     /**
 83      * 釋放資源
 84      */
 85     public static void releaseSource(){
 86         if(xl!=null){
 87             xl.invoke("Quit", new Variant[] {});
 88             xl = null;
 89         }
 90         workbooks = null;
 91         ComThread.Release();
 92         System.gc();
 93     }
 94     
 95     /**
 96      *  添加新的工做表(sheet),(添加後爲默認爲當前激活的工做表)
 97      */
 98     public Dispatch addSheet() {
 99         return Dispatch.get(Dispatch.get(workbook, "sheets").toDispatch(), "add").toDispatch();
100     }
101     
102     /**
103      * 修改當前工做表的名字
104      * @param newName
105      */
106     public void modifyCurrentSheetName(String newName) {
107         Dispatch.put(getCurrentSheet(), "name", newName);
108     }
109 
110     /**
111      * 獲得當前工做表的名字
112      * @return
113      */
114     public String getCurrentSheetName() {
115         return Dispatch.get(getCurrentSheet(), "name").toString();
116     }
117 
118     /**
119      * 獲得工做薄的名字
120      * @return
121      */
122     public String getWorkbookName() {
123         if(workbook==null)
124             return null;
125         return Dispatch.get(workbook, "name").toString();
126     }
127 
128     /**
129      *  獲得sheets的集合對象
130      * @return
131      */
132     public Dispatch getSheets() {
133         if(sheets==null)
134             sheets = Dispatch.get(workbook, "sheets").toDispatch();
135         return sheets;
136     }
137     
138     /**
139      * 獲得當前sheet
140      * @return
141      */
142     public Dispatch getCurrentSheet() {
143         currentSheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
144         return currentSheet;
145     }
146 
147     /**
148      * 經過工做表名字獲得工做表
149      * @param name sheetName
150      * @return
151      */
152     public Dispatch getSheetByName(String name) {
153         return Dispatch.invoke(getSheets(), "Item", Dispatch.Get, new Object[]{name}, new int[1]).toDispatch();
154     }
155     
156     /**
157      * 經過工做表索引獲得工做表(第一個工做簿index爲1)
158      * @param index
159      * @return  sheet對象
160      */
161     public Dispatch getSheetByIndex(Integer index) {
162         return Dispatch.invoke(getSheets(), "Item", Dispatch.Get, new Object[]{index}, new int[1]).toDispatch();
163     }
164 
165     /**
166      * 獲得sheet的總數
167      * @return
168      */
169     public int getSheetCount() {
170         int count = Dispatch.get(getSheets(), "count").toInt();
171         return count;
172     }
173     
174     /**
175      * 調用excel宏
176      * @param macroName 宏名
177      */
178     public void callMacro(String macroName){
179         Dispatch.call(xl, "Run",new Variant(macroName));
180     }
181     
182     /**
183      *  單元格寫入值
184      * @param sheet  被操做的sheet
185      * @param position 單元格位置,如:C1
186      * @param type 值的屬性 如:value
187      * @param value
188      */
189     public void setValue(Dispatch sheet, String position, String type, Object value) {
190 
191         Dispatch cell = Dispatch.invoke(sheet, "Range",
192                 Dispatch.Get, new Object[] { position }, new int[1])
193                 .toDispatch();
194         Dispatch.put(cell, type, value);
195     }
196     
197     /**
198      * 單元格讀取值
199      * @param position 單元格位置,如: C1
200      * @param sheet 
201      * @return
202      */
203     public Variant getValue(String position, Dispatch sheet) {
204         Dispatch cell = Dispatch.invoke(sheet, "Range", Dispatch.Get,
205                 new Object[] { position }, new int[1]).toDispatch();
206         Variant value = Dispatch.get(cell, "Value");
207         return value;
208     }
209     
210     private void initComponents(){
211         workbook = null;
212         currentSheet = null;
213         sheets = null;
214     }
215 }
jacob工具類

  調用宏代碼

 1 public void excelPictureGrab() throws Exception {
 2         this.targetFile = new File(targetFilePath);
 3         
 4         //複製文件
 5         FileUtils.copyFile(xlsFile, targetFile);
 6 
 7         logger.info("文件復至完成");
 8         
 9         //生成帶圖形的 excel
10         JacobExcelUtils tool = new JacobExcelUtils();
11         try {
12             tool.OpenExcel(targetFilePath, false, false);
13             
14             logger.info("打開Excel");
15             
16             //執行宏 複製爲圖片
17             tool.callMacro("copyImg");
18             
19             logger.info("處理宏完成");
20         } catch (Exception e) {
21             throw new Exception("執行宏出錯," + e.getMessage());
22             // TODO: handle exception
23         } finally {
24             // 關閉流
25             tool.CloseExcel(false, true);
26         }
27     }

 

五、  獲取圖表

 1 //獲取圖片字節流
 2 public static String getPic(String fileUrl,String backupUrl) throws Exception {
 3         StringBuffer results = new StringBuffer();
 4         
 5         File tfdir = new File(backupUrl);
 6         if (!tfdir.exists()) tfdir.mkdirs();
 7         
 8         InputStream inp = new FileInputStream(fileUrl);
 9         HSSFWorkbook workbook = (HSSFWorkbook) WorkbookFactory.create(inp);
10 
11         List<HSSFPictureData> pictures = workbook.getAllPictures();
12         HSSFSheet sheet = (HSSFSheet) workbook.getSheetAt(0); //全部圖片都存在第一頁
13         
14         int i = 0;
15         for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) {
16             HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
17 
18             if (shape instanceof HSSFPicture) {
19                 HSSFPicture pic = (HSSFPicture) shape;
20                 int pictureIndex = pic.getPictureIndex()-1;
21                 
22                 //圖片名稱
23                 int row = anchor.getRow1();
24                 
25                 System.out.println(anchor.getCol1());
26                 
27                 HSSFCell picCell =  sheet.getRow(row).getCell(anchor.getCol1());
28                 
29                 String picName = "";   
30                 if(picCell != null) {
31                     picName = picCell.getStringCellValue();
32                 }
33                
34                 
35                 logger.info(i + "--->row." + anchor.getRow1() + ":cell." + anchor.getCol1()  + ":pictureIndex." + pictureIndex);
36                 
37                 HSSFPictureData picData = pictures.get(pictureIndex);
38                 
39                 //備份並返回 圖片
40                 if(picName != null && !"".equals(picName)) {
41                      String result = BackupPic(picName, picData,backupUrl);
42                      results.append(result);
43                      results.append(",");
44                 }
45             }
46             i++;
47         }
48         
49         return results.toString();
50     }
51 
52     //備份圖片
53     private static String BackupPic(String picName,PictureData pic,String backupUrl) throws Exception {
54         String result = "";
55         
56         String pngImgUrl,jpgImgUrl;
57         String ext = pic.suggestFileExtension();
58         byte[] data = pic.getData();
59         if (ext.equals("png")) {
60             
61             pngImgUrl = backupUrl + picName + "." + ext;
62             FileOutputStream out = new FileOutputStream(
63                     pngImgUrl);
64             out.write(data);
65             out.close();
66             
67             //轉爲 jpg
68             jpgImgUrl = backupUrl + picName + ".jpg";
69             ConvertPngToJpg(pngImgUrl,jpgImgUrl);
70             
71             result = picName + ":" + DatatypeConverter.printBase64Binary(data);
72         }
73         
74         return result;
75     }
76     
77     //壓縮圖片 把PND圖片轉JPG 
78     private static void ConvertPngToJpg(String pngImgUrl,String jpgImgUrl) {
79         BufferedImage bufferedImage;
80       try {
81 
82           //read image file
83           bufferedImage = ImageIO.read(new File(pngImgUrl));
84 
85           // create a blank, RGB, same width and height, and a white background
86           BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
87                 bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
88           newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);
89 
90           // write to jpeg file
91           ImageIO.write(newBufferedImage, "jpg", new File(jpgImgUrl));
92 
93         } catch (IOException e) {
94 
95           e.printStackTrace();
96 
97         }
98     }
得到excel圖片
相關文章
相關標籤/搜索