项目需求:在PDF文件中生成柱状图
需求难点:使用网上大家提供能的代码只能完成生成柱状图,但是pdf中展示出来的效果是比较模糊的,尤其是在中文汉字上的表现,基本不能使用
功能实现:
1.相关jar包:
com.itextpdf
itext7-core
7.0.6
com.itextpdf
itext-asian
5.2.0
com.itextpdf
font-asian
7.1.16
org.jfree
jfreechart
1.5.4
org.jfree
jcommon
1.0.24
org.jfree
jfreesvg
3.4.3
org.apache.xmlgraphics
batik-transcoder
1.14
org.apache.xmlgraphics
batik-codec
1.14
2.实现原理:使用JFreeChart生成svg格式图片,然后使用batik.transcoder将svg图片转换成png格式图片,不经过svg转png过程直接生成png格式时图片模糊无法使用。
3.代码实现:
import java.awt.BasicStroke;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.fusesource.hawtbuf.ByteArrayInputStream;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.graphics2d.svg.SVGGraphics2D;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.color.DeviceRgb;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import com.minxue.util.common.DateUtils;
import com.minxue.util.common.PropertisUtil;
import com.minxue.util.common.StringUtil;
import com.minxue.util.pdf.VacationHoistEventHandlerA4SingleFaceOneCol;
import com.minxue.util.qrCode.QRCodeUtil;
/**
* @author Administrator
* @date 2023年11月23日
*/
public class PdfTablesTest {
public static void main(String[] args) {
try {
String studentId = "123456";
String temp = DateUtils.formatDateTimeToStr2(DateUtils.getNowTime());
String folder1 =PropertisUtil.getInstance().getTempDir() +File.separator +"VacationHoist";
File dirfolder1 = new File(folder1);
if (!dirfolder1.exists()){
dirfolder1.mkdirs();
dirfolder1.setReadable(true, false);
dirfolder1.setExecutable(true, false);
dirfolder1.setWritable(true, false);
}
String folder2 =PropertisUtil.getInstance().getTempDir() +File.separator +"VacationHoist"+File.separator+studentId;
File dirfolder2 = new File(folder2);
if (!dirfolder2.exists()){
dirfolder2.mkdirs();
dirfolder2.setReadable(true, false);
dirfolder2.setExecutable(true, false);
dirfolder2.setWritable(true, false);
}
String folder3 =PropertisUtil.getInstance().getTempDir() +File.separator +"VacationHoist"+File.separator+studentId +File.separator + temp;
File dirfolder3 = new File(folder3);
if (!dirfolder3.exists()){
dirfolder3.mkdirs();
dirfolder3.setReadable(true, false);
dirfolder3.setExecutable(true, false);
dirfolder3.setWritable(true, false);
}
//String doc1 = PropertisUtil.getInstance().getTempDir() +File.separator +"VacationHoist"+File.separator+studentId+File.separator + temp;
String fileName1 = PropertisUtil.getInstance().getTempDir() +File.separator +"VacationHoist"+File.separator+studentId+File.separator + temp+File.separator
+ "scoreAnaLysis_1.pdf";
String filepath = PropertisUtil.getInstance().getTempDir() + File.separator;
String qrcodeName = filepath +PropertisUtil.getInstance().getTemplate()+File.separator+ "qrLogo.jpg";
PageSize ps = PageSize.A4;
PdfFont sysFont1 = null;
String fonts_dir = PropertisUtil.getInstance().getFonts_dir();
sysFont1 = PdfFontFactory.createFont(fonts_dir, PdfEncodings.IDENTITY_H, false);
Document document = null;
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(fileName1));
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE,
new VacationHoistEventHandlerA4SingleFaceOneCol("西安xxxx中 高三(2031班) xxx【数学】 2024届高三入学摸底考试 数学", "https://wx.xxxxxx.com/wechat", qrcodeName, filepath));//传期数 账号
document = new Document(pdfDoc, ps);// 构建文档对象
createBarChar(document,sysFont1);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void createBarChar(Document document, PdfFont sysFont1) throws Exception {
//echart图表
DefaultCategoryDataset defaultCategoryDataset = new DefaultCategoryDataset();
defaultCategoryDataset.addValue(5,"其他人","160-150");
defaultCategoryDataset.addValue(20,"其他人","150-140");
defaultCategoryDataset.addValue(100,"其他人","140-130");
defaultCategoryDataset.addValue(11,"其他人","130-120");
defaultCategoryDataset.addValue(8,"其他人","120-110");
defaultCategoryDataset.addValue(5,"其他人","110-100");
defaultCategoryDataset.addValue(14,"我的位置","100-90");
defaultCategoryDataset.addValue(7,"其他人","90-80");
defaultCategoryDataset.addValue(30,"其他人","80-70");
defaultCategoryDataset.addValue(7,"其他人","70-60");
defaultCategoryDataset.addValue(8,"其他人","60-50");
defaultCategoryDataset.addValue(9,"其他人","50-40");
defaultCategoryDataset.addValue(4,"其他人","40-30");
defaultCategoryDataset.addValue(3,"其他人","30-20");
defaultCategoryDataset.addValue(2,"其他人","20-10");
defaultCategoryDataset.addValue(12,"其他人","10-0");
StandardChartTheme chartTheme = new StandardChartTheme("CN");
chartTheme.setExtraLargeFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD,8));
chartTheme.setRegularFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD,8));
chartTheme.setLargeFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD,8));
ChartFactory.setChartTheme(chartTheme);
//JFreeChart chart = ChartFactory.createBarChart("趋势图", "各项分布","比例分值",defaultCategoryDataset);
JFreeChart chart = ChartFactory.createBarChart("", "","人数",defaultCategoryDataset);
chart.setBackgroundPaint(java.awt.Color.white);
//chart.setTextAntiAlias(false);
//chart.setAntiAlias(true);
CategoryPlot categoryplot = chart.getCategoryPlot();// 图本身
org.jfree.chart.axis.CategoryAxis domainAxis = categoryplot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(70));
BarRenderer brender = new BarRenderer();
//设置柱子为平面效果
brender.setBarPainter(new StandardBarPainter());
brender.setSeriesPaint(0, java.awt.Color.decode("#61CAFF"));
brender.setSeriesPaint(1, java.awt.Color.decode("#78AB41"));
brender.setSeriesStroke(0, new BasicStroke(4));
brender.setSeriesStroke(0, new BasicStroke(4));
brender.setShadowVisible(false);
//设置柱状图的顶端显示数字
brender.setIncludeBaseInRange(true);
brender.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
brender.setDefaultItemLabelsVisible(true);
brender.setDefaultItemLabelFont(new java.awt.Font("微软雅黑", java.awt.Font.BOLD,8));
//brender.setBarPainter(new StandardBarPainter());// 标准的渲染器(支持颜色渐变)
brender.setItemMargin(0);
// 设置图的背景为白色
categoryplot.setBackgroundPaint(java.awt.Color.WHITE);
categoryplot.setRangeGridlinePaint(java.awt.Color.decode("#B6A2DE"));
categoryplot.setOutlineVisible(false);
categoryplot.setRenderer(brender);
SVGGraphics2D g2 = new SVGGraphics2D(500, 300);
java.awt.geom.Rectangle2D area = new java.awt.geom.Rectangle2D.Double(0, 0, 500, 300);
chart.draw(g2, area );
InputStream is = new ByteArrayInputStream(g2.getSVGDocument().getBytes());
OutputStream out = new FileOutputStream(new File("D:\\data\\mxjy_pdf\\VacationHoist\\x.png"));
out = new BufferedOutputStream(out);
Transcoder transcoder = new PNGTranscoder();
TranscoderInput input = new TranscoderInput(is);
TranscoderOutput output = new TranscoderOutput(out);
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, 1024f);
transcoder.addTranscodingHint(ImageTranscoder.KEY_HEIGHT, 614f);
transcoder.transcode(input, output);
Image image = new Image(ImageDataFactory.create("D:\\data\\mxjy_pdf\\VacationHoist\\x.png"));
document.add(image);
}
}
4.实现效果:
svg转png图片:
(1)JfreeChart之柱状图_jfreechart柱状图-CSDN博客
JFreeChart| 图解JFreeChart中的条形图/柱状图(BarChart)_jfreechart柱状图-CSDN博客
使用报表功能SpringBoot + itextpdf +JfreeEhart+vue实现后端饼图柱状图写进PDF一并导出后,摸鱼时间又长了_itextpdf 柱状图-CSDN博客