工作中需要生成波形图,并且嵌入到excel中,由于第一次这么处理,费了好大的精神,进行总结
之前的时候采用了 application的 方式进行处理,由于是代码调用,不需要手动处理点击确定之后再生成下一张图,还花费了长时间去了解application的源码,如何自动取消,并且这种方式只能调用一次,第二次调用的时候必须把第一次进程给kill 掉,才能进行第二次调用,采用了手动调用进程,并且手动kill掉进程,效果不太好,于是换了一种方式,采用的jfree 完美解决,并且生成速度也很快
首先引入jfree的pom:
// 直接拿走,可以生成
// 可以自定义图片名称,并且规定x y轴 的大小
//传入的数据 需要指定每张图的存放位置
package com.jxxxx.sys.report.util;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
@Component
public class GeneraterPic {
private static final int WIDTH = 350;
private static final int HEIGHT = 300;
public Boolean generaterPicForWave(List<Map<String,Object>> list) throws IOException {
// 创建数据系列
for(int j = 0;j<list.size() ;j++){
Map<String, Object> stringObjectMap = list.get(j);
String xstr = ""+stringObjectMap.get("seriaX");
String ystr = ""+stringObjectMap.get("seriaY");
String productCode = ""+stringObjectMap.get("productCode");
String filePath = ""+stringObjectMap.get("filePath");
String[] split = xstr.split(",");
String[] split1 = ystr.split(",");
XYSeries series = new XYSeries("Sine Wave");
for(int i = 0;i<split.length;i++){
series.add(Double.valueOf(split[i]), Double.valueOf(split1[i]));
}
// 将数据系列添加到数据集中
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series);
// 创建图表
JFreeChart chart = ChartFactory.createXYLineChart(
productCode, "ns", "V",
dataset);
// 设置图表样式
chart.setBackgroundPaint(Color.WHITE);
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
plot.setDomainPannable(true);
plot.setRangePannable(true);
// 设置X轴和Y轴的范围
NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
domainAxis.setRange(0, 100);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setRange(-1, 5);
// 设置数据系列的样式
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesPaint(0, Color.BLUE);
plot.setRenderer(renderer);
// 将图表添加到面板中
ChartPanel chartPanel = new ChartPanel(chart);
// 因为不需要窗口展示
// 创建窗口并显示图表
// JFrame frame = new JFrame("Waveform");
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(WIDTH, HEIGHT);
// frame.add(chartPanel);
// frame.setVisible(true);
// 生成图片
BufferedImage image = chart.createBufferedImage(WIDTH, HEIGHT);
String filename = productCode;
// String filename = UUID.randomUUID().toString();
File file = new File(filePath + filename + ".png");
ImageIO.write(image, "png", file);
}
return true;
}
// 进行自己测试生成
public static void main(String[] args) throws IOException {
String xstr = "0.3,0.6,0.9,1.2,1.5,1.8,2.1,2.4,2.7,3,3.3,3.6,3.9,4.2,4.5,4.8,5.1,5.4,5.7,6,6.3,6.6,6.9,7.2,7.5,7.8,8.1,8.4,8.7,9,9.3,9.6,9.9,10.2,10.5,10.8,11.1,11.4,11.7,12,12.3,12.6,12.9,13.2,13.5,13.8,14.1,14.4,14.7,15,15.3,15.6,15.9,16.2,16.5,16.8,17.1,17.4,17.7,18,18.3,18.6,18.9,19.2,19.5,19.8,20.1,20.4,20.7,21,21.3,21.6,21.9,22.2,22.5,22.8,23.1,23.4,23.7,24,24.3,24.6,24.9,25.2,25.5,25.8,26.1,26.4,26.7,27,27.3,27.6,27.9,28.2,28.5,28.8,29.1,29.4,29.7,30,30.3,30.6,30.9,31.2,31.5,31.8,32.1,32.4,32.7,33,33.3,33.6,33.9,34.2,34.5,34.8,35.1,35.4,35.7,36,36.3,36.6,36.9,37.2,37.5,37.8,38.1,38.4,38.7,39,39.3,39.6,39.9,40.2,40.5,40.8,41.1,41.4,41.7,42,42.3,42.6,42.9,43.2,43.5,43.8,44.1,44.4,44.7,45,45.3,45.6,45.9,46.2,46.5,46.8,47.1,47.4,47.7,48,48.3,48.6,48.9,49.2,49.5,49.8,50.1,50.4,50.7,51,51.3,51.6,51.9,52.2,52.5,52.8,53.1,53.4,53.7,54,54.3,54.6,54.9,55.2,55.5,55.8,56.1,56.4,56.7,57,57.3,57.6,57.9,58.2,58.5,58.8,59.1,59.4,59.7,60,60.3,60.6,60.9,61.2,61.5,61.8,62.1,62.4,62.7,63,63.3,63.6,63.9,64.2,64.5,64.8,65.1,65.4,65.7,66,66.3,66.6,66.9,67.2,67.5,67.8,68.1,68.4,68.7,69,69.3,69.6,69.9,70.2,70.5,70.8,71.1,71.4,71.7,72,72.3,72.6,72.9,73.2,73.5,73.8,74.1,74.4,74.7,75,75.3,75.6,75.9,76.2,76.5,76.8,77.1,77.4,77.7,78,78.3,78.6,78.9,79.2,79.5,79.8";
String ystr = "0.806,0.583,0.346,0.072,-0.167,-0.338,-0.37,-0.357,-0.298,-0.256,-0.234,-0.151,-0.068,0.021,0.068,0.11,0.105,0.093,0.078,0.074,0.047,0.009,-0.025,-0.066,-0.094,-0.111,-0.099,-0.116,-0.098,-0.06,-0.017,0.003,-0.001,0.013,0.016,0.009,-0.006,0.007,0.007,0.012,0.013,-0.005,-0.018,-0.011,-0.025,-0.035,-0.011,-0.011,-0.032,-0.002,0.008,0.005,0.012,0.003,-0.01,0.01,0.01,0.018,0.014,0.001,0.052,0.21,0.465,0.833,1.215,1.635,2.04,2.326,2.603,2.859,3.16,3.448,3.608,3.69,3.704,3.725,3.718,3.685,3.627,3.522,3.426,3.373,3.327,3.302,3.29,3.292,3.286,3.281,3.292,3.34,3.339,3.36,3.383,3.396,3.421,3.416,3.421,3.399,3.38,3.387,3.393,3.375,3.386,3.377,3.38,3.362,3.36,3.356,3.359,3.358,3.365,3.378,3.371,3.341,3.351,3.365,3.368,3.364,3.35,3.369,3.374,3.365,3.362,3.351,3.365,3.361,3.323,3.184,2.908,2.525,2.09,1.638,1.24,0.913,0.675,0.443,0.15,-0.111,-0.306,-0.394,-0.387,-0.348,-0.261,-0.199,-0.179,-0.085,-0.004,0.075,0.107,0.114,0.098,0.082,0.084,0.077,0.046,-0.009,-0.029,-0.07,-0.064,-0.097,-0.101,-0.081,-0.059,-0.036,-0.012,0.004,0.006,0.011,0.003,0.007,-0.008,-0.019,-0.026,-0.006,-0.034,-0.029,-0.017,-0.019,-0.028,-0.001,-0.005,-0.003,0.003,0.003,-0.008,0.016,0.004,-0.02,0.004,0.003,0.016,0.004,-0.002,0.041,0.153,0.356,0.706,1.094,1.487,1.897,2.215,2.477,2.765,3.065,3.356,3.59,3.673,3.715,3.721,3.728,3.722,3.65,3.569,3.463,3.392,3.334,3.308,3.286,3.28,3.313,3.278,3.272,3.3,3.336,3.337,3.39,3.392,3.421,3.423,3.42,3.411,3.411,3.402,3.396,3.382,3.366,3.362,3.369,3.371,3.378,3.369,3.362,3.373,3.364,3.37,3.385,3.36,3.403,3.391,3.379,3.37,3.37,3.368,3.369,3.369,3.381,3.367,3.346,3.357,3.339,3.228,3.028,2.684,2.211,1.768,1.345";
ArrayList<Map<String,Object>> strings = new ArrayList<>();
for(int i = 0;i<3;i++){
HashMap<String, Object> map = new HashMap<>();
map.put("xstr",xstr);
map.put("ystr",ystr);
strings.add(map);
}
// String[] split = xstr.split(",");
// String[] split1 = ystr.split(",");
// ArrayList<Map<String,String>> strings = new ArrayList<>();
// for(int i = 0;i<split.length;i++){
// HashMap<String, String> map = new HashMap<>();
// map.put("xstr",split[i]);
// map.put("ystr",split1[i]);
// strings.add(map);
// }
// for(int i = 0;i<split.length;i++){
// HashMap<String, String> map = new HashMap<>();
// map.put("xstr",split[i]);
// map.put("ystr",split1[i]);
// strings.add(map);
// }
// test(strings);
// String[] objects = (String [])strings.toArray(new String[0]);
}
}
// 放入自己指定的excel中,并且按每三张图 进行 换行处理
采用的是ClientAnchor 处理方式
// 最后打印图片
// 循环插入图片
// 图片行计数器
int rowCounter = 0;
int colCounter = 0;
for (int p = 0; p < fileList.size(); p++) {
// 此处为了设置图片应该从哪里开始 5:数据的结束行
if(p == 0){
rowCounter += titlerowline+1;
colCounter = 0;
}else{
// 为了 开启下一行的时候从第一列开始
if (p % 3 == 0) {
rowCounter += 5;
colCounter = 0;
}
}
// 创建行和单元格
Row row = sheet.createRow(rowCounter);
Cell cell = row.createCell(p % 3);
// 将图片插入单元格
File file = fileList.get(p);
byte[] imageBytes = trasferByteByFile(file);
// 将图片插入单元格
int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_JPEG);
CreationHelper helper = workbook.getCreationHelper();
Drawing drawing = sheet.createDrawingPatriarch();
/**
* col1:左上角单元格的列索引。
* row1:左上角单元格的行索引。
* col2:右下角单元格的列索引。
* row2:右下角单元格的行索引。
*/
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(colCounter);
anchor.setRow1(rowCounter);
anchor.setCol2(colCounter + 5);
anchor.setRow2(rowCounter + 6);
drawing.createPicture(anchor, pictureIdx);
// 每3张图片,移动到下一行
if ((colCounter + 1) % 5 == 0) {
colCounter = 0;
rowCounter++;
} else {
colCounter+=5;
}
经过一系列的耗费脑细胞 终于解决,长舒一口气,下次使用的时候直接方便拿取