主要是基于 jfreechart + itext
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
com.itextpdf
itextpdf
5.5.13
com.itextpdf
itext-asian
5.2.0
org.apache.commons
commons-lang3
3.9
org.apache.pdfbox
pdfbox
2.0.21
com.itextpdf.tool
xmlworker
5.5.13
org.springframework.boot
spring-boot-starter-thymeleaf
2.2.4.RELEASE
org.xhtmlrenderer
core-renderer
R8
ognl
ognl
3.3.2
org.freemarker
freemarker
2.3.29
commons-io
commons-io
2.6
commons-lang
commons-lang
2.6
org.jfree
jfreechart
1.5.0
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.meadel.export.demo01.PdfUtil;
import lombok.extern.slf4j.Slf4j;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* @author
* @version 1.0.0
* @Description TODO
* @createTime 2022年01月18日 09:34:00
*/
@Slf4j
@RestController
@RequestMapping("/demo4")
public class Demo4Controller {
@RequestMapping(value = "/test", method = {RequestMethod.GET})
public void test(HttpServletResponse response) throws Exception{
String filename = "测试pdf";
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8") + ".pdf");
OutputStream os = new BufferedOutputStream(response.getOutputStream());
// 1. Document document = new Document();
Document document = PdfUtil.createDocument();
// 2. 获取writer
PdfWriter.getInstance(document, os);
// 3. open()
document.open();
//设置中文样式(不设置,中文将不会显示)
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontChinese_content = new Font(bfChinese, 10, Font.NORMAL, BaseColor.BLACK);
/**
* 生成统计图
*/
PieDataset dataset = pieDataSet();
JFreeChart chart = ChartFactory.createPieChart3D(" 项目进度分布", dataset, true, true, false);
PiePlot3D plot=(PiePlot3D)chart.getPlot();
//设置Label字体
plot.setLabelFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD, 12));
//设置legend字体
chart.getLegend().setItemFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD, 12));
// 图片中显示百分比:默认方式
//plot.setLabelGenerator(new StandardPieSectionLabelGenerator(StandardPieToolTipGenerator.DEFAULT_TOOLTIP_FORMAT));
// 图片中显示百分比:自定义方式,{0} 表示选项, {1} 表示数值, {2} 表示所占比例 ,小数点后两位
plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}={1}({2})", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));
// 图例显示百分比:自定义方式, {0} 表示选项, {1} 表示数值, {2} 表示所占比例
plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("{0}={1}({2})"));
// 设置背景色为白色
chart.setBackgroundPaint(Color.white);
// 指定图片的透明度(0.0-1.0)
plot.setForegroundAlpha(1.0f);
// 指定显示的饼图上圆形(false)还椭圆形(true)
plot.setCircular(true);
// 设置图标题的字体
java.awt.Font font = new java.awt.Font(" 黑体",java.awt.Font.CENTER_BASELINE,20);
TextTitle title = new TextTitle("项目状态分布");
title.setFont(font);
chart.setTitle(title);
//图片存放位置
String templatePath = this.getClass().getResource("/").getPath() + "/templates/statistics.jpg";
try {
FileOutputStream fos_jpg=new FileOutputStream(templatePath);
ChartUtils.writeChartAsJPEG(fos_jpg,0.7f,chart,800,1000,null);
fos_jpg.close();
} catch (Exception e) {
e.printStackTrace();
}
document.newPage();
Paragraph pieParagraph = new Paragraph("02、饼状图测试", fontChinese_content);
pieParagraph.setAlignment(Paragraph.ALIGN_LEFT);
document.add(pieParagraph);
Image pieImage = Image.getInstance(templatePath);
pieImage.setAlignment(Image.ALIGN_CENTER);
pieImage.scaleAbsolute(328, 370);
document.add(pieImage);
/**
* 折线图
*/
CategoryDataset lineDataset = lineDataset();
JFreeChart lineChart = ChartFactory.createLineChart("java图书销量", "java图书", "销量", lineDataset, PlotOrientation.VERTICAL, true, true, true);
lineChart.getLegend().setItemFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));
//获取title
lineChart.getTitle().setFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 16));
//获取绘图区对象
CategoryPlot linePlot = lineChart.getCategoryPlot();
//设置绘图区域背景的 alpha 透明度 ,在 0.0f 到 1.0f 的范围内
linePlot.setBackgroundAlpha(0.0f);
//区域背景色
//linePlot.setBackgroundPaint(Color.white);
//背景底部横虚线
linePlot.setRangeGridlinePaint(Color.gray);
//linePlot.setOutlinePaint(Color.RED);//边界线
// 设置水平方向背景线颜色
// 设置是否显示水平方向背景线,默认值为true
linePlot.setRangeGridlinesVisible(true);
// 设置垂直方向背景线颜色
linePlot.setDomainGridlinePaint(Color.gray);
// 设置是否显示垂直方向背景线,默认值为false
linePlot.setDomainGridlinesVisible(true);
//获取坐标轴对象
CategoryAxis lineAxis = linePlot.getDomainAxis();
//设置坐标轴字体
lineAxis.setLabelFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));
//设置坐标轴标尺值字体(x轴)
lineAxis.setTickLabelFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));
//获取数据轴对象(y轴)
ValueAxis rangeAxis = linePlot.getRangeAxis();
rangeAxis.setLabelFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 12));
/*
* 生成图片
*/
try {
FileOutputStream fos = new FileOutputStream(templatePath);
ChartUtils.writeChartAsJPEG(fos, 0.7f, lineChart, 600, 300);
} catch (Exception e) {
e.printStackTrace();
}
Paragraph lineParagraph = new Paragraph("02、折线图测试", fontChinese_content);
lineParagraph.setAlignment(Paragraph.ALIGN_LEFT);
document.add(lineParagraph);
Image image = Image.getInstance(templatePath);
image.setAlignment(Image.ALIGN_CENTER);
image.scaleAbsolute(600, 300);
document.add(image);
// 5. close()
document.close();
os.close();
}
private static CategoryDataset lineDataset() {
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
//Spring架构
dataSet.addValue(6000, "Spring架构", "第一季度");
dataSet.addValue(3000, "Spring架构", "第二季度");
dataSet.addValue(12000, "Spring架构", "第三季度");
dataSet.addValue(9000, "Spring架构", "第四季度");
//Mysql解析
dataSet.addValue(5000, "Mysql解析", "第一季度");
dataSet.addValue(6000, "Mysql解析", "第二季度");
dataSet.addValue(18000, "Mysql解析", "第三季度");
dataSet.addValue(2000, "Mysql解析", "第四季度");
//redis原理
dataSet.addValue(9000, "redis原理", "第一季度");
dataSet.addValue(1000, "redis原理", "第二季度");
dataSet.addValue(15000, "redis原理", "第三季度");
dataSet.addValue(8000, "redis原理", "第四季度");
//Cloud深入
dataSet.addValue(16000, "Cloud深入", "第一季度");
dataSet.addValue(6000, "Cloud深入", "第二季度");
dataSet.addValue(10000, "Cloud深入", "第三季度");
dataSet.addValue(8000, "Cloud深入", "第四季度");
//SpringBoot
dataSet.addValue(9000, "SpringBoot", "第一季度");
dataSet.addValue(5000, "SpringBoot", "第二季度");
dataSet.addValue(3000, "SpringBoot", "第三季度");
dataSet.addValue(10000, "SpringBoot", "第四季度");
return dataSet;
}
private static PieDataset pieDataSet() {
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue(" 市场前期", new Double(10));
dataset.setValue(" 立项", new Double(15));
dataset.setValue(" 计划", new Double(10));
dataset.setValue(" 需求与设计", new Double(10));
dataset.setValue(" 执行控制", new Double(35));
dataset.setValue(" 收尾", new Double(10));
dataset.setValue(" 运维",new Double(10));
return dataset;
}
}
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
public class PdfUtil {
// 标准字体
public static Font NORMALFONT;
// 加粗字体
public static Font BOLDFONT;
//固定高
public static float fixedHeight = 27f;
//间距
public static int spacing = 5;
static {
try {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
NORMALFONT = new Font(bfChinese, 10, Font.NORMAL);
BOLDFONT = new Font(bfChinese, 14, Font.BOLD);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Document createDocument() {
//生成pdf
Document document = new Document();
// 页面大小
Rectangle rectangle = new Rectangle(PageSize.A4);
// 页面背景颜色
rectangle.setBackgroundColor(BaseColor.WHITE);
document.setPageSize(rectangle);
// 页边距 左,右,上,下
document.setMargins(20, 20, 20, 20);
return document;
}
/**
* @param text 段落内容
* @return
*/
public static Paragraph createParagraph(String text, Font font) {
Paragraph elements = new Paragraph(text, font);
elements.setSpacingBefore(5);
elements.setSpacingAfter(5);
elements.setSpacingAfter(spacing);
return elements;
}
public static Font createFont(int fontNumber, int fontSize, BaseColor fontColor) {
//中文字体 ----不然中文会乱码
BaseFont bf = null;
try {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
return new Font(bf, fontNumber, fontSize, fontColor);
} catch (Exception e) {
e.printStackTrace();
}
return new Font(bf, Font.DEFAULTSIZE, Font.NORMAL, BaseColor.BLACK);
}
/**
* 隐藏表格边框线
*
* @param cell 单元格
*/
public static void disableBorderSide(PdfPCell cell) {
if (cell != null) {
cell.disableBorderSide(1);
cell.disableBorderSide(2);
cell.disableBorderSide(4);
cell.disableBorderSide(8);
}
}
/**
* 创建居中得单元格
*
* @return
*/
public static PdfPCell createCenterPdfPCell() {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setFixedHeight(fixedHeight);
return cell;
}
/**
* 创建指定文字得单元格
*
* @param text
* @return
*/
public static PdfPCell createCenterPdfPCell(String text, int rowSpan, int colSpan, Font font) {
PdfPCell cell = new PdfPCell(new Paragraph(text, font));
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
cell.setFixedHeight(fixedHeight);
cell.setRowspan(rowSpan);
cell.setColspan(colSpan);
return cell;
}
/**
* @param len 表格列数
* @return
*/
public static PdfPTable createPdfPTable(int len) {
PdfPTable pdfPTable = new PdfPTable(len);
pdfPTable.setSpacingBefore(5);
pdfPTable.setHorizontalAlignment(Element.ALIGN_CENTER);
return pdfPTable;
}
}