大家好,我是曲不成歌,今天和大家分享下Jfree结合Itext生成一张PDF图表。
先分享下一个英文句子 I guess sometimes you don’t know what you want because you don’t know it exists. <我猜有时候你不知道自己想要什么,是因为你并不知道这东西的存在>
下图是生成的双页PDF展示
需要导入的jar
业务类(数据模板)
package industryStationExportDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.PieDataset;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class Demo {
static BaseFont bfChinese = null;
static Font title_font = null;
static Font key_font = null;
static Font normal_font = null;
static Font mini_font = null;
static Font en_font = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
exportPDF("E:/test/test11.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
static{
try {
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
title_font = new Font(bfChinese,15,Font.BOLD);
key_font = new Font(bfChinese,10,Font.BOLD);
normal_font = new Font(bfChinese,10,Font.NORMAL);
mini_font = new Font(bfChinese,6,Font.NORMAL);
}
@SuppressWarnings("rawtypes")
private static void exportPDF(String filepath) throws Exception {
Document document = new Document();
File file = new File(filepath);
FileOutputStream fos = null;
if(!file.exists()){
file.createNewFile();
fos = new FileOutputStream(file);
}
PdfWriter.getInstance(document, fos);
document.open();
//获取模拟数据部分
Map data = getTestData();
String pdfName = (String) data.get("pdfName");
List datas = (List) data.get("datas");
//填充pdf数据
Paragraph blank = new Paragraph(" ");//创建一个空的段落,备用
Paragraph p_name = new Paragraph(pdfName,title_font);//PDF主标题
p_name.setAlignment(Element.ALIGN_CENTER);//居中对齐
document.add(p_name);//将段落添加到document对象中
document.add(blank);//添加空白段落,避免上下文之间拥挤
document.add(blank);
Map data0 = (Map) datas.get(0);
addFirstTable(document,data0);//添加第一个表格
document.add(blank);
Map data1 = (Map) datas.get(1);
addSecondChart(document,data1);//添加第二个chart图表
document.add(blank);
Map data2 = (Map) datas.get(2);
addThirdChart(document,data2);//添加第三个chart图表
document.add(blank);
Map data3 = (Map) datas.get(3);
addFourthChart(document,data3);//添加第四个chart图表
document.add(blank);
Map data4 = (Map) datas.get(4);
addFifthTable(document,data4);//添加第五个chart图表
document.close();//关闭document对象
}
/**
* 这里使用内外嵌套表格实现,外表格1行 4列,内表格2行 5列
* @param document
* @param data
* @throws MalformedURLException
* @throws IOException
* @throws DocumentException
*/
private static void addFirstTable(Document document,Map data) throws MalformedURLException, IOException, DocumentException{
String[] head = (String[]) data.get("head");
String[] body = (String[]) data.get("body");
String[] image = (String[]) data.get("image");
document.add(new Paragraph(" ",normal_font));
PdfPTable table_out = new PdfPTable(4);//创建一个4列的表格
for(int i=0;i<4;i++){
PdfPCell cell_out = new PdfPCell();//用来装4个内置表格
cell_out.setBorderWidth(0);//设置表格边框线厚度为0 即不显示边框
cell_out.setUseAscender(true);//开启设置权限,否则下面设置的对齐会无效
cell_out.setUseDescender(true);
cell_out.setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
cell_out.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
PdfPTable table_in = new PdfPTable(5);//创建一个内置的5列的表格
for(int j=0;j<7;j++){//内置表格共7个格子
PdfPCell cell_in = new PdfPCell();
cell_in.setUseAscender(true);
cell_in.setUseDescender(true);
cell_in.setHorizontalAlignment(Element.ALIGN_CENTER);
cell_in.setVerticalAlignment(Element.ALIGN_MIDDLE);
Paragraph p1 = null;
/*
* 第一个格子,什么都不装,设置右下边框不可见
*/
if(j==0){
p1 = new Paragraph(" ",mini_font);
cell_in.addElement(p1);//将段落添加到格子中
cell_in.disableBorderSide(10);//设置边框线不可见
table_in.addCell(cell_in);//然后将格子添加到内置表格中
}
/*
* 第二格子,合并一个2行1列的单元格用来装图标,设置左右边框线不可见
*/
if(j==1){
cell_in.setRowspan(2);//合并单元格
cell_in.disableBorderSide(12);
String image_path = (String) image[i];
Image img = Image.getInstance(image_path);
cell_in.addElement(img);//将图标图片添加到格子中
table_in.addCell(cell_in);
}
/*
* 第三个格子,合并一个1行2列的单元格装类型(月收益),设置左右下边框不可见
*/
if(j==2){
cell_in.setColspan(2);
String head_str = (String) head[i];
p1 = new Paragraph(head_str.trim(),mini_font);
p1.setAlignment(Element.ALIGN_MIDDLE);
p1.setAlignment(Element.ALIGN_CENTER);
cell_in.disableBorderSide(14);
cell_in.addElement(p1);
table_in.addCell(cell_in);
}
/*
* 第四个格子,装空白段落
*/
if(j==3){
p1 = new Paragraph(" ",mini_font);
cell_in.addElement(p1);
cell_in.disableBorderSide(6);
table_in.addCell(cell_in);
}
/*
*第五个格子,装空白段落
*/
if(j==4){
p1 = new Paragraph(" ",mini_font);
cell_in.addElement(p1);
cell_in.disableBorderSide(9);
table_in.addCell(cell_in);
}
/*
* 第六个格子,合并一个1行2列的单元格装数值(¥26493.6),设置上左右边框不可见
*/
if(j==5){
cell_in.setColspan(2);
cell_in.disableBorderSide(13);
String body_str = (String) body[i];
p1 = new Paragraph(body_str,mini_font);
p1.setAlignment(Element.ALIGN_MIDDLE);
p1.setAlignment(Element.ALIGN_CENTER);
cell_in.addElement(p1);
table_in.addCell(cell_in);
}
/*
*第七个格子,装空白段落
*/
if(j==6){
p1 = new Paragraph(" ",mini_font);
cell_in.addElement(p1);
cell_in.disableBorderSide(5);
table_in.addCell(cell_in);
}
}
cell_out.addElement(table_in);//将添加好的数据的内表格,添加到外表格对应格子中
table_out.addCell(cell_out);
}
document.add(table_out);//添加表格对象
}
/**
* 创建一个1列2行表格,第一行为图表标题, 第二行装柱状图图表
* @param document
* @param data
* @throws MalformedURLException
* @throws IOException
* @throws DocumentException
*/
private static void addSecondChart(Document document,Map data) throws MalformedURLException, IOException, DocumentException{
String name = (String) data.get("name");
String xDesc = (String) data.get("xDesc");
String yDesc = (String) data.get("yDesc");
String[] legends = (String[]) data.get("legends");
String[] xData = (String[]) data.get("x");
double[][] y = (double[][]) data.get("y");
CategoryDataset dataset1 =BarImageUtil.getBarData(y, legends, xData);
String img_name = name+System.currentTimeMillis()+".png";
//通过柱状图工具获取生成的柱状图图片地址
String img_path = BarImageUtil.createBarChart(dataset1,null, xDesc, yDesc,"","",img_name,false);
PdfPTable table = new PdfPTable(1);
table.setSpacingBefore(15f);
PdfPCell cell0 = new PdfPCell();
cell0.setUseAscender(true);
cell0.setUseDescender(true);
cell0.setHorizontalAlignment(Element.ALIGN_CENTER);
cell0.setVerticalAlignment(Element.ALIGN_MIDDLE);
Paragraph p = new Paragraph(name,normal_font);
p.setAlignment(Element.ALIGN_MIDDLE);
cell0.addElement(p);
PdfPCell cell1 = new PdfPCell();
Image img = Image.getInstance(img_path);
img.setBorder(0);
cell1.addElement(img);
table.addCell(cell0);
table.addCell(cell1);
document.add(table);
}
/**
* 创建一个1列2行表格,第一行为图表标题, 第二行装饼图图表
* @param document
* @param data
* @throws MalformedURLException
* @throws IOException
* @throws DocumentException
*/
private static void addThirdChart(Document document,Map data) throws MalformedURLException, IOException, DocumentException{
String name = (String) data.get("name");
String[] head = (String[]) data.get("head");
double[] body = (double[]) data.get("body");
PieDataset pset = PileImageUtil.getDataPieSetByUtil(body, head);
String img_name = name+System.currentTimeMillis()+".png";
String img_path = PileImageUtil.createValidityComparePimChar(pset, "", img_name, head);
PdfPTable table = new PdfPTable(1);
table.setSpacingBefore(50f);
PdfPCell cell0 = new PdfPCell();
cell0.setUseAscender(true);
cell0.setUseDescender(true);
cell0.setHorizontalAlignment(Element.ALIGN_CENTER);
cell0.setVerticalAlignment(Element.ALIGN_MIDDLE);
Paragraph p = new Paragraph(name,normal_font);
p.setAlignment(Element.ALIGN_MIDDLE);
cell0.addElement(p);
PdfPCell cell1 = new PdfPCell();
Image img = Image.getInstance(img_path);
img.setBorder(0);
cell1.addElement(Image.getInstance(img_path));
table.addCell(cell0);
table.addCell(cell1);
document.add(table);
}
/**
* 创建一个1列2行表格,第一行为图表标题, 第二行装柱状图/饼图混合图表
* @param document
* @param data
* @throws MalformedURLException
* @throws IOException
* @throws DocumentException
*/
private static void addFourthChart(Document document,Map data) throws MalformedURLException, IOException, DocumentException{
String name = (String) data.get("name");
String yDesc1 = (String) data.get("yDesc1");
String yDesc2 = (String) data.get("yDesc2");
String[] xData = (String[]) data.get("x");
double[][] y1 = (double[][]) data.get("y1");
double[][] y2 = (double[][]) data.get("y2");
String[] legend1 = (String[]) data.get("legend1");
String[] legend2 = (String[]) data.get("legend2");
CategoryDataset dataset1 =BarImageUtil.getBarData(y1, legend1, xData);
CategoryDataset dataset2 =BarImageUtil.getBarData(y2, legend2, xData);
String img_name = name+System.currentTimeMillis()+".png";
String img_path = BarImageUtil.createBarChart(dataset1,dataset2, "", yDesc1,yDesc2,"",img_name,true);
PdfPTable table = new PdfPTable(1);
table.setSpacingBefore(80f);
//table.setSplitLate(false);//禁止表格切割
PdfPCell cell0 = new PdfPCell();
cell0.setUseAscender(true);
cell0.setUseDescender(true);
cell0.setHorizontalAlignment(Element.ALIGN_CENTER);
cell0.setVerticalAlignment(Element.ALIGN_MIDDLE);
Paragraph p = new Paragraph(name,normal_font);
p.setAlignment(Element.ALIGN_MIDDLE);
cell0.addElement(p);
PdfPCell cell1 = new PdfPCell();
Image img = Image.getInstance(img_path);
img.setBorder(0);
cell1.addElement(img);
table.addCell(cell0);
table.addCell(cell1);
document.add(table);;
}
/**
* 内置双层表格, 内置表格标题格子,设置边框宽度为0 合并为一行
* @param document
* @param data
* @throws DocumentException
*/
private static void addFifthTable(Document document,Map data) throws DocumentException{
String name = (String) data.get("name");
String[] datas = (String[]) data.get("datas");
PdfPTable table = new PdfPTable(1);//外表格
table.setSpacingBefore(50f);//设置当前表格与上一个表格间距为50
PdfPCell cell_out1 = new PdfPCell();//外表格第一个格子 基本信息
cell_out1.setUseAscender(true);
cell_out1.setUseDescender(true);
cell_out1.setHorizontalAlignment(Element.ALIGN_CENTER);
cell_out1.setVerticalAlignment(Element.ALIGN_MIDDLE);
Paragraph p = new Paragraph(name,normal_font);
p.setAlignment(Element.ALIGN_MIDDLE);
cell_out1.addElement(p);//外表格第二个格子 装内置表格
PdfPCell cell_out2 = new PdfPCell();
//创建一个内置10列的表格
PdfPTable table_in = new PdfPTable(10);
PdfPCell cell0 = new PdfPCell();//第一个格子 合并一个10列的单元格 装 "电站信息"
cell0.setColspan(10);
cell0.setBorderWidth(0);
cell0.addElement(new Paragraph(datas[0],normal_font));
PdfPCell cell1 = new PdfPCell();//第二个格子 合并一个2列的单元格 装 "子阵数量"
cell1.setColspan(2);
cell1.addElement(new Paragraph(" "+datas[1],normal_font));
PdfPCell cell2 = new PdfPCell();//第三个格子 合并一个3列的单元格 装 "1"
cell2.setColspan(3);
cell2.addElement(new Paragraph(" "+datas[2],normal_font));
PdfPCell cell3 = new PdfPCell();
cell3.setColspan(2);
cell3.addElement(new Paragraph(" "+datas[3],normal_font));
PdfPCell cell4 = new PdfPCell();
cell4.setColspan(3);
cell4.addElement(new Paragraph(" "+datas[4],normal_font));
PdfPCell cell5 = new PdfPCell();
cell5.setColspan(2);
cell5.addElement(new Paragraph(" "+datas[5],normal_font));
PdfPCell cell6 = new PdfPCell();
cell6.setColspan(3);
cell6.addElement(new Paragraph(" "+datas[6],normal_font));
PdfPCell cell7 = new PdfPCell();
cell7.setColspan(2);
cell7.addElement(new Paragraph(" "+datas[7],normal_font));
PdfPCell cell8 = new PdfPCell();
cell8.setColspan(3);
cell8.addElement(new Paragraph(" "+datas[8],normal_font));
PdfPCell cell9 = new PdfPCell();
cell9.setColspan(2);
cell9.addElement(new Paragraph(" "+datas[9],normal_font));
PdfPCell cell10 = new PdfPCell();
cell10.setColspan(8);
cell10.addElement(new Paragraph(" "+datas[10],normal_font));
PdfPCell cell11 = new PdfPCell();
cell11.setColspan(2);
cell11.addElement(new Paragraph(" "+datas[11],normal_font));
PdfPCell cell12 = new PdfPCell();
cell12.setColspan(8);
cell12.addElement(new Paragraph(" "+datas[12],normal_font));
PdfPCell cell13 = new PdfPCell();//合并一个10列的单元格 装"智能分析"
cell13.setBorderWidth(0);
cell13.setColspan(10);
cell13.addElement(new Paragraph(datas[13],normal_font));
PdfPCell cell14 = new PdfPCell();
cell14.setColspan(2);
cell14.addElement(new Paragraph(" "+datas[14],normal_font));
PdfPCell cell15 = new PdfPCell();
cell15.setColspan(3);
cell15.addElement(new Paragraph(" "+datas[15],normal_font));
PdfPCell cell16 = new PdfPCell();
cell16.setColspan(2);
cell16.addElement(new Paragraph(" "+datas[16],normal_font));
PdfPCell cell17 = new PdfPCell();
cell17.setColspan(3);
cell17.addElement(new Paragraph(" "+datas[17],normal_font));
PdfPCell cell18 = new PdfPCell();
cell18.setColspan(2);
cell18.addElement(new Paragraph(" "+datas[18],normal_font));
PdfPCell cell19 = new PdfPCell();
cell19.setColspan(8);
cell19.addElement(new Paragraph(" "+datas[19],normal_font));
table_in.addCell(cell0);
table_in.addCell(cell1);
table_in.addCell(cell2);
table_in.addCell(cell3);
table_in.addCell(cell4);
table_in.addCell(cell5);
table_in.addCell(cell6);
table_in.addCell(cell7);
table_in.addCell(cell8);
table_in.addCell(cell9);
table_in.addCell(cell10);
table_in.addCell(cell11);
table_in.addCell(cell12);
table_in.addCell(cell13);
table_in.addCell(cell14);
table_in.addCell(cell15);
table_in.addCell(cell16);
table_in.addCell(cell17);
table_in.addCell(cell18);
table_in.addCell(cell19);
cell_out2.addElement(table_in);
table.addCell(cell_out1);
table.addCell(cell_out2);
document.add(table);
}
/**
* 封装测试数据
* @return
*/
public static Map<?,?> getTestData(){
Map map = new HashMap();
List datas = new ArrayList();
//E02报表
Map item1 = new HashMap();
String[] head1 = {"月收益","月发电量","月问题数","月告警数"};
String[] data1 = {"¥ 26493.6","20379.7kwh","15","107"};
String[] image1 = {
"D:\\Desktop\\sy.png",
"D:\\Desktop\\fdl.png",
"D:\\Desktop\\wt.png",
"D:\\Desktop\\gj.png"
};
item1.put("head", head1);
item1.put("body", data1);
item1.put("image", image1);
//发电量统计
Map item2 = new HashMap();
String[] xdata2 = {"1","2","3","4","5","6","7","8","9","10","11","12"};
String[] legends = {""};//图例
double[][] ydata2 = {
{215656.53,254213.00,146546.32,182132.54,152132.23,322325.28,345321.62,371212.24,394564.75,251515.04,215465.45,175465}
};
item2.put("legends", legends);
item2.put("name", "发电量统计");
item2.put("x", xdata2);
item2.put("xDesc", "月份");
item2.put("y", ydata2);
item2.put("yDesc", "发电量: KWH");
//告警统计
Map item3 = new HashMap();
String[] head3 = {"紧急故障数","次要故障数"};
double[] body3 = {100,7};
item3.put("name", "告警统计");
item3.put("head", head3);
item3.put("body", body3);
//社会价值统计
Map item4 = new HashMap();
String[] xdata4 = {"1","2","3","4","5","6","7","8","9","10","11","12"};
double[][] ydata4 = {
{532,275,343,444,521,663,708,806,655,512,208,212},
{53,27,34,44,52,66,70,80,65,51,20,21}
};
double[][] ydatat = {
{103,77,84,94,102,66,120,130,115,101,70,71}
};
String[] legend1 = {"CO2减排","节约标准煤"};
String[] legend2 = {"减少森林砍伐"};
item4.put("name", "问题统计");
item4.put("x", xdata4);
item4.put("yDesc1", "单位:kg");
item4.put("y1", ydata4);
item4.put("yDesc2", "单位:棵");
item4.put("y2", ydatat);
item4.put("legend1", legend1);
item4.put("legend2", legend2);
//基本信息
Map item5 = new HashMap();
String[] body5 = {
"电站信息","子阵数量","1","逆变器数量","1346","组串数量","187","电站面积","11","电站模式","自发自用","电站概述","",
"智能分析信息","分析类型","电站级IV诊断","故障组串数","0","最新诊断时间","2020-5-4 10:52:01"
};
item5.put("name", "基本信息");
item5.put("datas", body5);
datas.add(item1);
datas.add(item2);
datas.add(item3);
datas.add(item4);
datas.add(item5);
map.put("pdfName", "月报表");
map.put("datas", datas);
return map;
}
}
柱状图工具类
package industryStationExportDemo;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.ui.TextAnchor;
/**
* 多组柱状图测试类
* @author Administrator
*
*/
public class BarImageUtil {
private static final String CHART_PATH = "E:/test/";
public static void main(String[] args) {
// TODO Auto-generated method stub
makeBarGroupChart();
}
public static void makeBarGroupChart(){
double[][] data = new double[][]{
{10,12,2,0,1,2,7},
{5250.00,33,4,0,7,3,26},
{5247.00,1794,592,18,297,73,751}
};
String[] rowKeys = { "待跟进数", "未完成数", "已完成数" };
String[] columnKeys = { "中国", "欧洲", "亚洲", "泰国", "美洲", "非洲", "澳洲" };
CategoryDataset dataset = getBarData(data, rowKeys, columnKeys);
double[][] data2 = new double[][]{
{1452.0,1620.0,1800.0,1532.0,1365.0,2163.0,1709.0}
};
String[] columnKeys2 = { "CO2减排" };
String[] rowKeys2 = { "中国", "欧洲", "亚洲", "泰国", "美洲", "非洲", "澳洲" };
CategoryDataset dataset2 = DatasetUtilities.createCategoryDataset(columnKeys2, rowKeys2, data2);
createBarChart(dataset,null,"","单位:kg","单位:棵","","柱状图6.png",false);
}
public static CategoryDataset getBarData(double[][] data, String[] rowKeys,String[] columnKeys){
return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
}
/**
* 柱状图
*
*@param dataset 数据集
* @param xName x轴的说明
* @param yName 左y轴的说明
* @param yName2 右y轴的说明
* @param chartTitle 图标题
* @param charName 生成图片的名字
* @return
*/
public static String createBarChart(CategoryDataset dataset1, CategoryDataset dataset2,String xName,String yName,String yName2, String chartTitle, String charName,boolean flag){
JFreeChart chart = ChartFactory.createBarChart(chartTitle, // 图表标题
xName, // 目录轴的显示标签
yName, // 数值轴的显示标签
dataset1, // 数据集0
PlotOrientation.VERTICAL, // 图表方向:水平、垂直
flag, // 是否显示图例(对于简单的柱状图必须是false)
false, // 是否生成工具
false // 是否生成URL链接
);
Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12);
/*
* VALUE_TEXT_ANTIALIAS_OFF表示将文字的抗锯齿关闭,
* 使用的关闭抗锯齿后,字体尽量选择12到14号的宋体字,这样文字最清晰好看
*/
chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
chart.setTextAntiAlias(false);
chart.setBackgroundPaint(Color.white);
// create plot
CategoryPlot plot = chart.getCategoryPlot();
// 设置横虚线可见
plot.setRangeGridlinesVisible(true);
// 虚线色彩
plot.setRangeGridlinePaint(Color.gray);
// 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确)
//plot.setBackgroundPaint(new Color(255, 255, 204));
// x轴设置
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setLabelFont(labelFont);// 轴标题
domainAxis.setTickLabelFont(labelFont);// 轴数值
domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);// 横轴上的 Lable 是否完整显示
domainAxis.setLowerMargin(0.02);// 设置距离图片左端距离
domainAxis.setUpperMargin(0.02);// 设置距离图片右端距离
plot.setDomainAxis(domainAxis);
// y轴设置
/*NumberAxis vn = (NumberAxis) plot.getRangeAxis();
vn.setAutoRangeIncludesZero(true);
DecimalFormat df = new DecimalFormat("#0.00");
vn.setNumberFormatOverride(df); */
ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setLabelFont(labelFont);
rangeAxis.setTickLabelFont(labelFont);
// 设置最高的一个 Item 与图片顶端的距离
rangeAxis.setUpperMargin(0.15);
// 设置最低的一个 Item 与图片底端的距离
rangeAxis.setLowerMargin(0.15);
plot.setRangeAxis(0,rangeAxis);
BarRenderer renderer = new BarRenderer();
// 设置柱子宽度
//renderer.setMaximumBarWidth(1.0);
// 设置柱子间距
renderer.setItemMargin(0);
// 设置柱子高度
renderer.setMinimumBarLength(0.3);
// 设置柱子边框颜色
renderer.setBaseOutlinePaint(Color.BLACK);
// 设置柱子边框可见
renderer.setDrawBarOutline(true);
// 显示每个柱的数值,并修改该数值的字体属性
renderer.setBaseItemLabelFont(labelFont);
renderer.setIncludeBaseInRange(true);
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
renderer.setSeriesPaint(0, new Color(106,162,255));//设置第一个柱状体颜色
renderer.setSeriesPaint(1, new Color(124,203,196));//设置第二个柱状体颜色,后续柱状体颜色自动填充
renderer.setAutoPopulateSeriesFillPaint(true);//自动填充柱状体颜色
//设置柱状体数值标签展示样式,此设置表示:在柱状体顶部左边显示,按左下定点向上旋转0.7角度
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE10,TextAnchor.BASELINE_LEFT, TextAnchor.BOTTOM_LEFT,-0.7D));
// 设置柱的透明度
plot.setForegroundAlpha(1.0f);
plot.setRenderer(renderer);
//双Y坐标轴设置
if(null!=dataset2){
NumberAxis numberaxis3 = new NumberAxis(yName2);
/*numberaxis3.setNumberFormatOverride(NumberFormat.getInstance());//设置风格
numberaxis3.setAutoRange(false);
numberaxis3.setLowerMargin(0.02D);//数据轴左边距
numberaxis3.setUpperMargin(0.02D);//右边距 */
plot.setRangeAxis(1, numberaxis3);//添加第二个坐标轴
plot.setDataset(1, dataset2);//设置数据集索引
plot.mapDatasetToRangeAxis(1,1);//将该索引映射到axis 第一个参数指数据集的索引,第二个参数为坐标轴的索引
LineAndShapeRenderer lineandshaperenderer = new LineAndShapeRenderer();
lineandshaperenderer.setBaseShapesVisible(true); // series 点(即数据点)可见
lineandshaperenderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见
lineandshaperenderer.setBaseItemLabelsVisible(true); // 显示折点数据
lineandshaperenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
lineandshaperenderer.setSeriesPaint(0,Color.GREEN);
//设置某坐标轴索引上数据集的显示样式
plot.setRenderer(1, lineandshaperenderer);
plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
}
FileOutputStream fos_jpg = null;
try{
isChartPathExist(CHART_PATH);
String chartName = CHART_PATH + charName;
fos_jpg = new FileOutputStream(chartName);
ChartUtilities.writeChartAsPNG(fos_jpg, chart, 800, 500, true, 10);
return chartName;
} catch (Exception e){
e.printStackTrace();
return null;
} finally {
try {
fos_jpg.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
private static void isChartPathExist(String chartPath){
File file = new File(chartPath);
if (!file.exists()) {
file.mkdirs();
}
}
}
饼图工具类
package industryStationExportDemo;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.RingPlot;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.SortOrder;
/**
* 饼状图 测试类
* @author Administrator
*
*/
public class PileImageUtil {
private static final String CHART_PATH = "E:/test/";
public static void main(String[] args) {
// 生成饼状图
makePieChart();
}
/**
* 测试逆变器数据
*/
public static void makePieChart(){
String[] keys = { "中国", "亚洲","非洲","欧洲","美洲","大洋洲" };
double[] data = { 336854, 16986,681,109535,14285,8028 };
String img_title = "逆变器总数(单位:台)";
String img_name = "饼状图4.png";
PieDataset pset = getDataPieSetByUtil(data, keys);
createValidityComparePimChar(pset, img_title,img_name, keys);
}
// 饼状图 数据集
public static PieDataset getDataPieSetByUtil(double[] data,String[] datadescription){
if (data != null && datadescription != null){
if (data.length == datadescription.length){
DefaultPieDataset dataset = new DefaultPieDataset();
for (int i = 0; i < data.length; i++){
dataset.setValue(datadescription[i], data[i]);
}
return dataset;
}
}
return null;
}
/**
* 饼状图
*
* @param dataset 数据集
* @param chartTitle 图标题
* @param charName 生成图的名字
* @param pieKeys 分饼的名字集
* @return
*/
public static String createValidityComparePimChar(PieDataset dataset,String chartTitle, String charName, String[] pieKeys){
JFreeChart chart = ChartFactory.createRingChart(chartTitle,dataset, true,true,false);
//饼图面积降序排序
((DefaultPieDataset) dataset).sortByValues(SortOrder.DESCENDING);
// 使下说明标签字体清晰,去锯齿类似于
chart.setTextAntiAlias(false);
// 图片背景色
chart.setBackgroundPaint(Color.white);
// 设置图标题的字体重新设置title
Font font = new Font("隶书", Font.BOLD, 25);
TextTitle title = new TextTitle(chartTitle);
title.setFont(font);
chart.setTitle(title);
RingPlot plot = (RingPlot) chart.getPlot();
plot.setBackgroundAlpha(0.8f);
plot.setSectionPaint(pieKeys[0], new Color(250, 100, 0));
plot.setSectionPaint(pieKeys[1], new Color(247, 181, 0));
// 设置无数据时的信息
//plot.setNoDataMessage("无对应的数据,请重新查询。");
// 设置无数据时的信息显示颜色
//plot.setNoDataMessagePaint(Color.red);
((DefaultPieDataset) dataset).sortByValues(SortOrder.DESCENDING);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator(
"{0}:{1}({2})", NumberFormat.getNumberInstance(),
new DecimalFormat("0.00%")));
// 图例显示百分比:自定义方式, {0} 表示选项, {1} 表示数值, {2} 表示所占比例
//{0}={1}({2}) 中国=103920(70%)
plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("{0}"));
plot.setLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT, 12));
// 指定图片的透明度(0.0-1.0)
plot.setForegroundAlpha(1.0f);
// 指定显示的饼图上圆形(false)椭圆形(true)
plot.setCircular(true);
FileOutputStream fos_jpg = null;
try{
isChartPathExist(CHART_PATH);
String chartName = CHART_PATH + charName;
fos_jpg = new FileOutputStream(chartName);
// 高宽的设置影响椭圆饼图的形状
ChartUtilities.writeChartAsPNG(fos_jpg, chart, 1000, 460);
return chartName;
}catch (Exception e){
e.printStackTrace();
return null;
}finally{
try{
fos_jpg.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* 判断文件夹是否存在,如果不存在则新建
* @param chartPath
*/
private static void isChartPathExist(String chartPath){
File file = new File(chartPath);
if (!file.exists()) {
file.mkdirs();
}
}
}
推荐下Jfree中文API文档, 另感谢大佬的cell边框设置无效的示例
> https://www.yiibai.com/jfreechart/jfreechart_referenced_apis.html
>
> https://blog.csdn.net/qq_37481877/article/details/88329958