使用itextpdf、jfree、transcoder生成清晰的柱状图

项目需求:在PDF文件中生成柱状图

需求难点:使用网上大家提供能的代码只能完成生成柱状图,但是pdf中展示出来的效果是比较模糊的,尤其是在中文汉字上的表现,基本不能使用

功能实现:

1.相关jar包:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.0.6</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>font-asian</artifactId>
    <version>7.1.16</version>
</dependency> 
<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.5.4</version>
</dependency>
<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jcommon</artifactId>
    <version>1.0.24</version>
</dependency>
<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreesvg</artifactId>
    <version>3.4.3</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-transcoder</artifactId>
    <version>1.14</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-codec</artifactId>
    <version>1.14</version>
</dependency>

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博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值