跟据客户的要求,需要开发一套包括图形的报表,还需要导出WORD

图表需要这样:

这样:

  

这样:

  

还有这样:

  

接下来是实现思路:

  以往用的最多的就是JFreechart,手上也有实现各种图形的资源,但是领导说用它做的图形太丑了, 所以没什么卵用。

  FusionCharts到是漂亮,但是没有办法实现上述图表,客户也不能接受替代方案,同样没什么卵用

  然后就是百度ECharts,漂亮、功能强大、灵活性强(JS/HTML5实现,可以随意更改源码), 但是有些功能不支待IE8, 还是没什么卵用

想了很多方法,最后又回到了原点,客户要生成Office, 就让Office给我们做,虽然Java对操作图表还没有什么好的方法,但是jacob是可以操作宏,我们通过宏实现所有图表功能。

1、 制作Excel图表模板
  制作图表看起来简单,但是做起来相当的慢,好在客户提供一些类似图表,我做了一些调整就可以了  膜拜。。。。。

  还有就是网上一堆的制作图表的教程,就不记录了。

2、 通过POI填充数据到Excel

 /**
* 通过填充excel 生成图表
* @param list 图标数据
* @param inFile 模板文件
* @param outFile 输出文件
* @return
* @throws Exception
*/
public static void createChart(List<Map> list, String inFile,String outFile) {
if(list == null) list = new ArrayList(); System.out.println("图表个数" + list.size());
System.out.println("源文件路径" + inFile);
System.out.println("图表个数" + outFile); try {
// 读取模板
FileInputStream is = new FileInputStream(inFile);
HSSFWorkbook wbs = new HSSFWorkbook(is); int sheetIndex;
HSSFSheet sheet; //sheet
int rowIndex;
HSSFRow row; //行
int cellIndex;
HSSFCell cell; //列
String value;
float fvalue;
String valStr = "^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$"; List<Integer> sheetList = new ArrayList();
for(Map tempMap:list) {
// 读取工作表(data)
sheetIndex = Integer.parseInt(tempMap.get("SHEETINDEX") + "");
sheet = wbs.getSheetAt(sheetIndex-);
sheetList.add(sheetIndex); /*
int i = 0;
List<HSSFPictureData> pictures = wbs.getAllPictures();
for (HSSFPictureData picData : pictures) {
String ext = picData.suggestFileExtension();
byte[] data = picData.getData();
System.out.println(data.length); //savePic(row, picData);
/*
String ext = picData.suggestFileExtension(); byte[] data = picData.getData();
if (ext.equals("jpeg")) {
FileOutputStream out = new FileOutputStream(
"D:\\Users\\Fancy1_Fan\\桌面\\work\\pict" + i + ".jpg");
out.write(data);
out.close();
}
if (ext.equals("png")) {
FileOutputStream out = new FileOutputStream(
"D:\\Users\\Fancy1_Fan\\桌面\\work\\pict" + i + ".png");
out.write(data);
out.close();
}*//*
i++;
}*/ //添加行
rowIndex = Integer.parseInt(tempMap.get("ROWINDEX") + "");
row = sheet.getRow(rowIndex-);
if(row == null) row = sheet.createRow(rowIndex-); //列
cellIndex = Integer.parseInt(tempMap.get("CELLINDEX") + "");
cell = row.getCell(cellIndex-); value = tempMap.get("DATAINFO") + "";
if(value.matches(valStr)) {
fvalue = Float.parseFloat(value); cell.setCellValue(fvalue);
} else {
cell.setCellValue(value);
}
//cell.setCellValue(tempMap.get("DATAINFO") + ""); //数据列
}
for(int temp:sheetList) {
sheet = wbs.getSheetAt(temp-);
sheet.setForceFormulaRecalculation(true);
} // 输出文件
FileOutputStream os = new FileOutputStream(outFile);
wbs.write(os);
is.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}

操作EXCEL,填充数据

3、 生成宏

我的基本思路是把所有生成的图片复至到一个指定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 = -
Selection.ShapeRange.PictureFormat.Crop.PictureOffsetY = -
Selection.Copy
Range("A1").Select
ActiveSheet.Pictures.Paste.Select
ActiveCell.FormulaR1C1 = "QGJYFJLXSQK"

复制单元格生成图形

只要会VBA 基本语法,其它的如果不会,可以通过录制宏得到

4、  调用宏

  先提供工具类

 package com.wiseda.fc.utils;

 import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant; public class JacobExcelUtils {
private static ActiveXComponent xl = null; //Excel对象(防止打开多个)
private static Dispatch workbooks = null; //工作簿对象
private Dispatch workbook = null; //具体工作簿
private Dispatch sheets = null;// 获得sheets集合对象
private Dispatch currentSheet = null;// 当前sheet public ActiveXComponent getXl() {
return xl;
} public Dispatch getWorkbooks() {
return workbooks;
} public Dispatch getWorkbook() {
return workbook;
} /**
* 打开excel文件
* @param filepath 文件路径名称
* @param visible 是否显示打开
* @param readonly 是否只读方式打开
*/
public void OpenExcel(String filepath, boolean visible, boolean readonly) {
try {
initComponents(); //清空原始变量
ComThread.InitSTA();
if(xl==null)
xl = new ActiveXComponent("Excel.Application"); //Excel对象
xl.setProperty("Visible", new Variant(visible));//设置是否显示打开excel
if(workbooks==null)
workbooks = xl.getProperty("Workbooks").toDispatch(); //工作簿对象
workbook = Dispatch.invoke( //打开具体工作簿
workbooks,
"Open",
Dispatch.Method,
new Object[] { filepath, new Variant(false),
new Variant(readonly) },// 是否以只读方式打开
new int[]).toDispatch();
} catch (Exception e) {
e.printStackTrace();
releaseSource();
}
} /**
* 工作簿另存为
* @param filePath 另存为的路径
*/
public void SaveAs(String filePath){
Dispatch.invoke(workbook, "SaveAs", Dispatch.Method,
new Object[] { filePath,
new Variant() }, new int[]);
} /**
* 关闭excel文档
* @param f 含义不明 (关闭是否保存?默认false)
*/
public void CloseExcel(boolean f,boolean quitXl) {
try {
Dispatch.call(workbook, "Save");
Dispatch.call(workbook, "Close", new Variant(f));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(quitXl){
releaseSource();
}
}
} /**
* 释放资源
*/
public static void releaseSource(){
if(xl!=null){
xl.invoke("Quit", new Variant[] {});
xl = null;
}
workbooks = null;
ComThread.Release();
System.gc();
} /**
* 添加新的工作表(sheet),(添加后为默认为当前激活的工作表)
*/
public Dispatch addSheet() {
return Dispatch.get(Dispatch.get(workbook, "sheets").toDispatch(), "add").toDispatch();
} /**
* 修改当前工作表的名字
* @param newName
*/
public void modifyCurrentSheetName(String newName) {
Dispatch.put(getCurrentSheet(), "name", newName);
} /**
* 得到当前工作表的名字
* @return
*/
public String getCurrentSheetName() {
return Dispatch.get(getCurrentSheet(), "name").toString();
} /**
* 得到工作薄的名字
* @return
*/
public String getWorkbookName() {
if(workbook==null)
return null;
return Dispatch.get(workbook, "name").toString();
} /**
* 得到sheets的集合对象
* @return
*/
public Dispatch getSheets() {
if(sheets==null)
sheets = Dispatch.get(workbook, "sheets").toDispatch();
return sheets;
} /**
* 得到当前sheet
* @return
*/
public Dispatch getCurrentSheet() {
currentSheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
return currentSheet;
} /**
* 通过工作表名字得到工作表
* @param name sheetName
* @return
*/
public Dispatch getSheetByName(String name) {
return Dispatch.invoke(getSheets(), "Item", Dispatch.Get, new Object[]{name}, new int[]).toDispatch();
} /**
* 通过工作表索引得到工作表(第一个工作簿index为1)
* @param index
* @return sheet对象
*/
public Dispatch getSheetByIndex(Integer index) {
return Dispatch.invoke(getSheets(), "Item", Dispatch.Get, new Object[]{index}, new int[]).toDispatch();
} /**
* 得到sheet的总数
* @return
*/
public int getSheetCount() {
int count = Dispatch.get(getSheets(), "count").toInt();
return count;
} /**
* 调用excel宏
* @param macroName 宏名
*/
public void callMacro(String macroName){
Dispatch.call(xl, "Run",new Variant(macroName));
} /**
* 单元格写入值
* @param sheet 被操作的sheet
* @param position 单元格位置,如:C1
* @param type 值的属性 如:value
* @param value
*/
public void setValue(Dispatch sheet, String position, String type, Object value) { Dispatch cell = Dispatch.invoke(sheet, "Range",
Dispatch.Get, new Object[] { position }, new int[])
.toDispatch();
Dispatch.put(cell, type, value);
} /**
* 单元格读取值
* @param position 单元格位置,如: C1
* @param sheet
* @return
*/
public Variant getValue(String position, Dispatch sheet) {
Dispatch cell = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { position }, new int[]).toDispatch();
Variant value = Dispatch.get(cell, "Value");
return value;
} private void initComponents(){
workbook = null;
currentSheet = null;
sheets = null;
}
}

jacob工具类

  调用宏代码

 public void excelPictureGrab() throws Exception {
this.targetFile = new File(targetFilePath); //复制文件
FileUtils.copyFile(xlsFile, targetFile); logger.info("文件复至完成"); //生成带图形的 excel
JacobExcelUtils tool = new JacobExcelUtils();
try {
tool.OpenExcel(targetFilePath, false, false); logger.info("打开Excel"); //执行宏 复制为图片
tool.callMacro("copyImg"); logger.info("处理宏完成");
} catch (Exception e) {
throw new Exception("执行宏出错," + e.getMessage());
// TODO: handle exception
} finally {
// 关闭流
tool.CloseExcel(false, true);
}
}

5、  获取图表

 //获取图片字节流
public static String getPic(String fileUrl,String backupUrl) throws Exception {
StringBuffer results = new StringBuffer(); File tfdir = new File(backupUrl);
if (!tfdir.exists()) tfdir.mkdirs(); InputStream inp = new FileInputStream(fileUrl);
HSSFWorkbook workbook = (HSSFWorkbook) WorkbookFactory.create(inp); List<HSSFPictureData> pictures = workbook.getAllPictures();
HSSFSheet sheet = (HSSFSheet) workbook.getSheetAt(0); //所有图片都存在第一页 int i = 0;
for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) {
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); if (shape instanceof HSSFPicture) {
HSSFPicture pic = (HSSFPicture) shape;
int pictureIndex = pic.getPictureIndex()-1; //图片名称
int row = anchor.getRow1(); System.out.println(anchor.getCol1()); HSSFCell picCell = sheet.getRow(row).getCell(anchor.getCol1()); String picName = "";
if(picCell != null) {
picName = picCell.getStringCellValue();
} logger.info(i + "--->row." + anchor.getRow1() + ":cell." + anchor.getCol1() + ":pictureIndex." + pictureIndex); HSSFPictureData picData = pictures.get(pictureIndex); //备份并返回 图片
if(picName != null && !"".equals(picName)) {
String result = BackupPic(picName, picData,backupUrl);
results.append(result);
results.append(",");
}
}
i++;
} return results.toString();
} //备份图片
private static String BackupPic(String picName,PictureData pic,String backupUrl) throws Exception {
String result = ""; String pngImgUrl,jpgImgUrl;
String ext = pic.suggestFileExtension();
byte[] data = pic.getData();
if (ext.equals("png")) { pngImgUrl = backupUrl + picName + "." + ext;
FileOutputStream out = new FileOutputStream(
pngImgUrl);
out.write(data);
out.close(); //转为 jpg
jpgImgUrl = backupUrl + picName + ".jpg";
ConvertPngToJpg(pngImgUrl,jpgImgUrl); result = picName + ":" + DatatypeConverter.printBase64Binary(data);
} return result;
} //压缩图片 把PND图片转JPG
private static void ConvertPngToJpg(String pngImgUrl,String jpgImgUrl) {
BufferedImage bufferedImage;
try { //read image file
bufferedImage = ImageIO.read(new File(pngImgUrl)); // create a blank, RGB, same width and height, and a white background
BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null); // write to jpeg file
ImageIO.write(newBufferedImage, "jpg", new File(jpgImgUrl)); } catch (IOException e) { e.printStackTrace(); }
}

获得excel图片

JAVA生成EXCEL图表的更多相关文章

  1. java 生成Excel开门篇

    本随笔的Excel所用的poi jar包(3.17版本)链接: https://pan.baidu.com/s/1gaa3dJueja8IraUDYCSLIQ 提取密码: 9xr7 简单实现:两个类: ...

  2. oracle PL/SQL调用Java生成Excel

    现在有个需求,  要求编写oracle存储过程生成Excel文件到指定目录,  但是oracle自己的API貌似不太给力,  所以只能通过另一种更强大的语言来实现了  ——Java.有一个Java框架 ...

  3. JAVA生成EXCEL模板

    JAVA生成excel模板,支持1.必填字段前加 红色 * 2.定义可选值下拉列表 valList3.定义名称并通过名称设置可选值 refName(名称在sheet2,sheet2自动隐藏)4.支持设 ...

  4. 使用poi和jfreechart生成excel图表图片

    最近项目在频繁的操作excel,里边涉及到很多和图表有关的东西.有时候需要使用java操作excel自带的图标,比较复杂的我们都是使用excel模板的形式实现. 除此之外,也有一些功能只需要生成对应的 ...

  5. [转]java生成 excel 并导出文件

    原文:https://blog.csdn.net/xunwei0303/article/details/53213130 目前,比较常用的实现Java导入.导出Excel的技术有两种Jakarta P ...

  6. 两种方式实现java生成Excel

    Web应用中难免会遇到需要将数据导出并生成excel文件的需求.同样,对于本博客中的总结,也是建立在为了完成这样的一个需求,才开始去了解其实现形式,并且顺利完成需求的开发,先将实现过程总结于此.本博文 ...

  7. Java生成excel导出文件(使用poi+JXL)

    1.使用poi生成文件 package com.mi.entity; import java.util.Date; public class Student { private int id; pri ...

  8. python生成Excel图表(通过xlsxwriter)

    前面介绍了pandas的简单用法,pandas的数据可以通过matlab第三方包将数据生成报表,但是我想将报表生成在Excel中,这时候就可以借助xlsxwriter第三方包来生成图标   缺点:xl ...

  9. java生成excel报表文件

    此次简单的操作将数据从数据库导出生成excel报表以及将excel数据导入数据库 首先建立数据库的连接池: package jdbc; import java.io.FileInputStream; ...

随机推荐

  1. iOS开发-数据持久化

    iOS中四种最常用的将数据持久存储在iOS文件系统的机制 前三种机制的相同点都是需要找到沙盒里面的Documents的目录路径,附加自己相应的文件名字符串来生成需要的完整路径,再往里面创建.读取.写入 ...

  2. maven for eclipse在线安装

    在线安装 地址变了下面的: http://download.eclipse.org/technology/m2e/releases      Eclipse Indigo安装Maven插件Maven ...

  3. Cts框架解析(12)-ITargetPreparer

    測试开启前的设备系统准备工作. 接口 /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Ap ...

  4. android短信发送器源代码

    Activity类: import java.util.List;import android.app.Activity;import android.app.PendingIntent;import ...

  5. [Canvas] Make Canvas Responsive to Pixel Ratio

    Canvas is great for high performance graphics rendering but by default the results look blocky on ph ...

  6. setAnimationTransition:forView:cache: 运行动画时背景色问题

    首先我描写叙述一下问题:当我从一个view到另外一个view的时候? 解答:这个问题的解决还须要看setAnimationTransition:forView:cache: 官方Api,官方是这样说的 ...

  7. Linux pipe函数

    1. 函数说明 pipe(建立管道): 1) 头文件 #include<unistd.h> 2) 定义函数: int pipe(int filedes[2]); 3) 函数说明: pipe ...

  8. Arrays.sort(new String[]{"aaa"}); 排序方法

    private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off) { int length ...

  9. C++赋值运算符函数

    为类添加赋值运算符函数: 类型定义 class CMyString { public: CMyString(char *pData = NULL); CMyString(const CMyString ...

  10. 整型数组与vector对象之间的相互初始化

    #include<iostream> #include<vector> #include<string> using namespace std; int main ...