美文网首页
jfree+easypoi实现数据报表导出下载

jfree+easypoi实现数据报表导出下载

作者: 莫须有的呓语 | 来源:发表于2021-03-22 10:51 被阅读0次

    基于springboot+mybatis,数据库mysql

    模板样例: 模板样例.png 效果样例: 图表效果.png

    1.pom文件

            <!--报表相关-->
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-base</artifactId>
                <version>4.1.0</version>
            </dependency>
            <dependency>
                <groupId>org.jfree</groupId>
                <artifactId>jcommon</artifactId>
                <version>1.0.24</version>
            </dependency>
            <dependency>
                <groupId>org.jfree</groupId>
                <artifactId>jfreechart</artifactId>
                <version>1.5.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
    

    2.JfreeUtil 文件(用于生成图表,更多图表样式等前往官网查找)

    package com.bonc.huanghai.manage.util;
    
    import cn.afterturn.easypoi.entity.ImageEntity;
    import lombok.extern.slf4j.Slf4j;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartUtils;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.StandardChartTheme;
    import org.jfree.chart.axis.CategoryAxis;
    import org.jfree.chart.axis.CategoryLabelPositions;
    import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
    import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
    import org.jfree.chart.plot.CategoryPlot;
    import org.jfree.chart.plot.DatasetRenderingOrder;
    import org.jfree.chart.plot.PiePlot;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.renderer.category.BarRenderer;
    import org.jfree.chart.renderer.category.LineAndShapeRenderer;
    import org.jfree.chart.renderer.category.StackedBarRenderer;
    import org.jfree.chart.renderer.category.StandardBarPainter;
    import org.jfree.data.category.CategoryDataset;
    import org.jfree.data.category.DefaultCategoryDataset;
    import org.jfree.data.general.DefaultPieDataset;
    import org.springframework.util.Assert;
    
    import java.awt.*;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.List;
    
    
    /**
     * @ClassName:JfreeUtil
     * @author:莫须有
     * @Description: 生成word文档中的图表(JPG)
     * @create:2020/2/13 19:22
     * @Version1.0
     */
    
    @Slf4j
    public class JfreeUtil {
        /**
         * 临时文件存储,也可以设置读取配置文件
         */
        private static String tempImgPath = "/data/app/server/weixin/tempJfree.jpeg";
        /**
         * 横纵轴等字体
         */
        private static Font font = new Font("宋体", Font.PLAIN, 12);
        /**
         *  颜色循环列表
         */
        private static final Paint[] COLORS = { new Color(65, 105, 255),new Color(0, 191, 255),
                                                new Color(30, 144, 223),new Color(30, 70, 255),
                                                new Color(0, 0, 200), new Color(0, 0, 150)
                                                };
    
        /**
         * 将图片转化为字节数组
         * @return 字节数组
         */
        private static byte[] imgToByte(){
            File file = new File(tempImgPath);
            byte[] buffer = null;
            FileInputStream fis = null;
            ByteArrayOutputStream bos = null;
            try {
                fis = new FileInputStream(file);
                bos = new ByteArrayOutputStream(1000);
                byte[] b = new byte[1000];
                int n;
                while ((n = fis.read(b)) != -1) {
                    bos.write(b, 0, n);
                }
                buffer = bos.toByteArray();
            } catch (IOException e) {
                log.error(e.getMessage());
            }finally {
                try {
                    if(fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(bos!= null) {
                        bos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //删除临时文件
                file.delete();
    
            }
            return buffer;
        }
    
        /**
         * 生成主题样式,及避免乱码
         * @return standardChartTheme
         */
        private static StandardChartTheme getChartTheme() {
            // 处理中文乱码
            // 创建主题样式
            StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
            //设置标题字体
            standardChartTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 15));
            //设置图例的字体
            standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 12));
            //设置轴向的字体
            standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 12));
            return standardChartTheme;
        }
    
        /**
         * 生成饼图
         * @param title 标题
         * @param data 数据集 {String,Number}
         * @param width 图片宽度
         * @param height 图片高度
         * @return 图像对象
         */
        public static ImageEntity pieChart(String title, List<Object[]> data, int width, int height) {
    
            //设置主题样式
            StandardChartTheme standardChartTheme = JfreeUtil.getChartTheme();
            ChartFactory.setChartTheme(standardChartTheme);
    
            //根据jfree生成一个本地饼状图数据集
            DefaultPieDataset dataset = new DefaultPieDataset();
            for (Object[] arr : data) {
                dataset.setValue((String) arr[0], (Number) arr[1]);
            }
            //创建图表  (图标标题、数据集合、是否显示图例标识、是否显示tooltips、是否支持超链接)
            JFreeChart chart = ChartFactory.createPieChart(title, dataset, true, false, false);
    
            //设置抗锯齿
            chart.setTextAntiAlias(false);
            //图例
            chart.getLegend().setItemFont(font);
            //图片边框
            chart.setBorderVisible(true);
            chart.setBorderPaint(Color.gray);
            //得到绘图区
            PiePlot plot = (PiePlot) chart.getPlot();
            plot.setNoDataMessage("暂无数据");
            //忽略无值的分类
            plot.setIgnoreNullValues(true);
            plot.setBackgroundAlpha(0f);
            plot.setOutlineVisible(false);
            //设置标签阴影颜色
            plot.setShadowPaint(new Color(255,255,255));
            //设置标签生成器(默认{0})
            plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}({1})/{2}"));
            //设置标签字体
            plot.setLabelFont(font);
            //设置标签背景色
            plot.setLabelBackgroundPaint(new Color(255,255,255));
            //扇区分离与颜色设置
            for (int i=0;i<dataset.getItemCount();i++) {
                plot.setExplodePercent(dataset.getKey(i), 0.02);
                plot.setSectionPaint(dataset.getKey(i).toString(), COLORS[i % COLORS.length]);
            }
    
            try {
                ChartUtils.saveChartAsJPEG(new File(tempImgPath), chart, width, height);
            } catch (IOException e1) {
                log.error("生成饼状图失败!");
            }
            ImageEntity imageEntity = new ImageEntity(imgToByte(), width, height);
            Assert.notNull(imageEntity.getData(),"生成饼状图对象失败!");
            return imageEntity;
        }
    
    
    
        public static ImageEntity barChart(String title, String xName, String yName, List<Object[]> data, int width, int height){
            return barChart(title, xName, yName, data,width,height,false);
        }
    
        /**
         * 生成垂直柱形图
         * @param title
         * @param xName
         * @param yName
         * @param data
         * @param width
         * @param height
         * @param legend
         * @return 图片
         */
        public static ImageEntity barChart(String title, String xName, String yName, List<Object[]> data, int width, int height,Boolean legend) {
            //设置主题样式
            StandardChartTheme standardChartTheme = JfreeUtil.getChartTheme();
            ChartFactory.setChartTheme(standardChartTheme);
    
            //数据集
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            for (Object[] arr : data) {
                dataset.setValue((Number) arr[0], (String) arr[1],(String) arr[2]);
            }
    
            //创建图表
            JFreeChart chart = ChartFactory.createBarChart(title, xName,yName,dataset, PlotOrientation.VERTICAL,legend,true,false);
            //设置抗锯齿
            chart.setTextAntiAlias(false);
            //图片边框
            chart.setBorderVisible(true);
            chart.setBorderPaint(Color.gray);
    
    
            //得到绘图区
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
    
            //获取渲染对象
            BarRenderer barRenderer = (BarRenderer)plot.getRenderer();
            //设置柱形图的宽度
            barRenderer.setMaximumBarWidth(0.07);
            //最短的BAR长度,避免数值太小而显示不出
            barRenderer.setMinimumBarLength(0.5);
            // 设置柱形图上的文字偏离值
            barRenderer.setItemLabelAnchorOffset(10D);
            //设置柱子的最大宽度
            // 设置柱状图之间的距离0.1代表10%
            barRenderer.setItemMargin(0.000000005);
            //设置柱子为平面图不是立体的
            barRenderer.setBarPainter(new StandardBarPainter());
            // 设置颜色
            barRenderer.setSeriesPaint(0,new Color(65,105,225));
            //不显示阴影
            barRenderer.setShadowVisible(false);
            //显示数值
            barRenderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            barRenderer.setDefaultItemLabelFont(font);
            barRenderer.setItemLabelAnchorOffset(0.1D);
            barRenderer.setDefaultItemLabelsVisible(true);
            for (int i=0;i<dataset.getRowCount();i++) {
                barRenderer.setSeriesPaint(i, COLORS[i % COLORS.length]);
            }
    
            CategoryAxis domainAxis = plot.getDomainAxis();
            // 右边距 边框距离,防止最后边的一个数据靠近了坐标轴。
            domainAxis.setUpperMargin(0.06);
            // 横轴 lable 的位置 横轴上的 Lable 45度倾斜
            domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
    
            //设置网格背景颜色
            plot.setBackgroundPaint(Color.white);
            //设置网格横线颜色
            plot.setRangeGridlinePaint(Color.black);
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);
            //设置范围轴(纵轴)字体
            plot.getRangeAxis().setLabelFont(font);
            //设置外边框不可见
            plot.setOutlineVisible(false);
    
            try {
                ChartUtils.saveChartAsJPEG(new File(tempImgPath), chart, width, height);
            } catch (IOException e1) {
                log.error("生成柱形图失败!");
            }
            ImageEntity imageEntity = new ImageEntity(imgToByte(), width, height);
            Assert.notNull(imageEntity.getData(),"生成柱形图对象失败!");
            return imageEntity;
        }
    
        /**
         *  堆叠柱形图
         * @param title
         * @param xName
         * @param yName
         * @param data
         * @param width
         * @param height
         * @return
         */
        public static ImageEntity stackedBarChart(String title, String xName, String yName, List<Object[]> data, int width, int height) {
    
            //设置主题样式
            StandardChartTheme standardChartTheme = JfreeUtil.getChartTheme();
            ChartFactory.setChartTheme(standardChartTheme);
    
    
            //数据集
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            for (Object[] arr : data) {
                dataset.setValue((Number) arr[0], (String) arr[1],(String) arr[2]);
            }
            //图标标题、数据集合、是否显示图例标识、是否显示tooltips、是否支持超链接
            JFreeChart chart = ChartFactory.createStackedBarChart(title, xName,yName,dataset);
            //设置抗锯齿
            chart.setTextAntiAlias(false);
            //设置提示条字体
            chart.getLegend().setItemFont(font);
            //图片边框
            chart.setBorderVisible(true);
            chart.setBorderPaint(Color.gray);
    
            //得到绘图区
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
    
            //获取渲染对象
            StackedBarRenderer stackedBarRenderer = (StackedBarRenderer)plot.getRenderer();
            //设置柱形图的宽度
            stackedBarRenderer.setMaximumBarWidth(0.07);
            //最短的BAR长度,避免数值太小而显示不出
            stackedBarRenderer.setMinimumBarLength(0.5);
            // 设置柱形图上的文字偏离值
            stackedBarRenderer.setItemLabelAnchorOffset(10D);
            //设置柱子的最大宽度
            // 设置柱状图之间的距离0.1代表10%
            stackedBarRenderer.setItemMargin(0.000000005);
            //设置柱子为平面图不是立体的
            stackedBarRenderer.setBarPainter(new StandardBarPainter());
            //不显示阴影
            stackedBarRenderer.setShadowVisible(false);
            //设置颜色
            for (int i=0;i<dataset.getRowCount();i++) {
                stackedBarRenderer.setSeriesPaint(i, COLORS[i % COLORS.length]);
            }
            //显示数值
            stackedBarRenderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            stackedBarRenderer.setDefaultItemLabelFont(font);
            stackedBarRenderer.setItemLabelAnchorOffset(0.1D);
            stackedBarRenderer.setDefaultItemLabelsVisible(true);
    
            CategoryAxis domainAxis = plot.getDomainAxis();
            // 右边距 边框距离,防止最后边的一个数据靠近了坐标轴。
            domainAxis.setUpperMargin(0.06);
            // 横轴 lable 的位置 横轴上的 Lable 45度倾斜
            domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
    
    
            //设置网格背景颜色
            plot.setBackgroundPaint(Color.white);
            //设置网格横线颜色
            plot.setRangeGridlinePaint(Color.black);
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);
            //设置范围轴(纵轴)字体
            plot.getRangeAxis().setLabelFont(font);
            //设置外边框不可见
            plot.setOutlineVisible(false);
    
            try {
                ChartUtils.saveChartAsJPEG(new File(tempImgPath), chart, width, height);
            } catch (IOException e1) {
                log.error("生成柱形图失败!");
            }
            ImageEntity imageEntity = new ImageEntity(imgToByte(), width, height);
            Assert.notNull(imageEntity.getData(),"生成柱形图对象失败!");
            return imageEntity;
        }
    
        /**
         * 折线图 柱形图 组合
         * @param title
         * @param xName
         * @param yName
         * @param barData
         * @param lineData
         * @param width
         * @param height
         * @return
         */
        public static ImageEntity lineBarChart(String title, String xName, String yName, List<Object[]> barData, List<Object[]> lineData,int width, int height) {
    
            //设置主题样式
            StandardChartTheme standardChartTheme = JfreeUtil.getChartTheme();
            ChartFactory.setChartTheme(standardChartTheme);
    
            //数据集
            DefaultCategoryDataset barDataset = new DefaultCategoryDataset();
            for (Object[] arr : barData) {
                barDataset.setValue((Number) arr[0], (String) arr[1],(String) arr[2]);
            }
            //数据集
            DefaultCategoryDataset lineDataset = new DefaultCategoryDataset();
            for (Object[] arr : lineData) {
                lineDataset.setValue((Number) arr[0], (String) arr[1],(String) arr[2]);
            }
    
            //图标标题、数据集合、是否显示图例标识、是否显示tooltips、是否支持超链接
            JFreeChart chart = ChartFactory.createBarChart(title, xName,yName,barDataset,PlotOrientation.VERTICAL,false,true,false);
            //设置抗锯齿
            chart.setTextAntiAlias(false);
            //图片边框
            chart.setBorderVisible(true);
            chart.setBorderPaint(Color.gray);
    
            //得到绘图区
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
    
            //设置网格背景颜色
            plot.setBackgroundPaint(Color.white);
            //设置网格横线颜色
            plot.setRangeGridlinePaint(Color.black);
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);
            //设置范围轴(纵轴)字体
            plot.getRangeAxis().setLabelFont(font);
            //设置外边框不可见
            plot.setOutlineVisible(false);
    
            //获取渲染对象
            BarRenderer barRenderer = (BarRenderer)plot.getRenderer();
            //设置柱形图的宽度
            barRenderer.setMaximumBarWidth(0.07);
            //最短的BAR长度,避免数值太小而显示不出
            barRenderer.setMinimumBarLength(0.5);
            // 设置柱形图上的文字偏离值
            barRenderer.setItemLabelAnchorOffset(10D);
            //设置柱子的最大宽度
            // 设置柱状图之间的距离0.1代表10%
            barRenderer.setItemMargin(0.000000005);
            //设置柱子为平面图不是立体的
            barRenderer.setBarPainter(new StandardBarPainter());
            // 设置颜色
            barRenderer.setSeriesPaint(0,new Color(65,105,225));
            //不显示阴影
            barRenderer.setShadowVisible(false);
            //显示数值
            barRenderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            barRenderer.setDefaultItemLabelFont(font);
            barRenderer.setItemLabelAnchorOffset(0.1D);
            barRenderer.setDefaultItemLabelsVisible(true);
    
            CategoryAxis domainAxis = plot.getDomainAxis();
            // 右边距 边框距离,防止最后边的一个数据靠近了坐标轴。
            domainAxis.setUpperMargin(0.06);
            // 横轴 lable 的位置 横轴上的 Lable 45度倾斜
            domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
    
            //放折线图数据
            CategoryDataset categorydataset = lineDataset;
            // 0显示是柱状图,1显示折线图
            plot.setDataset(1, categorydataset);
            // 显示折线图,0,0坐标轴都在左侧
            plot.mapDatasetToRangeAxis(0, 0);
            plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
            //画折线图
            LineAndShapeRenderer lineandshaperenderer = new LineAndShapeRenderer();
            // 设置实线
            BasicStroke realLine = new BasicStroke(3.0f);
            lineandshaperenderer.setSeriesStroke(0, realLine);
            //去掉折线的点
            lineandshaperenderer.setDefaultShapesVisible(false);
            //显示数值
            lineandshaperenderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            lineandshaperenderer.setDefaultItemLabelFont(font);
            lineandshaperenderer.setDefaultItemLabelPaint(new Color(80,30,0));
            lineandshaperenderer.setItemLabelAnchorOffset(0.2D);
            lineandshaperenderer.setDefaultItemLabelsVisible(true);
            plot.setRenderer(1, lineandshaperenderer);
    
            try {
                ChartUtils.saveChartAsJPEG(new File(tempImgPath), chart, width, height);
            } catch (IOException e1) {
                log.error("生成折线柱形图失败!");
            }
            ImageEntity imageEntity = new ImageEntity(imgToByte(), width, height);
            Assert.notNull(imageEntity.getData(),"生成折线柱形图对象失败!");
            return imageEntity;
        }
    }
    

    2.DownReportUtil 文件(下载生成的文件)

    package com.bonc.huanghai.manage.util;
    
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.activation.MimetypesFileTypeMap;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.net.URLEncoder;
    
    /**
     * @author:莫须有
     * @Description: 下载文件工具类
     * @create:2020/3/9 9:35
     * @Version1.0
     */
    public class DownReportUtil {
    
        /**
         * 下载文件,可以下载后删除
         * @param pathname
         * @param fileName
         * @throws IOException
         */
        public static void download(String pathname, String fileName) throws IOException {
            // 读取filename
            File file = new File(pathname);
            BufferedInputStream bis = null;
            OutputStream outputStream = null;
            if (file.isFile() && file.exists()) {
                try {
                    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                    HttpServletResponse response = requestAttributes.getResponse();
                    // 设置信息给客户端不解析
                    String type = new MimetypesFileTypeMap().getContentType(fileName);
                    // 设置contenttype,即告诉客户端所发送的数据属于什么类型
                    response.setHeader("Content-type", type);
                    // 设置编码
                    String encoded = URLEncoder.encode(fileName, "utf-8");
                    // 设置扩展头,当Content-Type 的类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型。
                    response.setHeader("Content-Disposition", "attachment;filename=" + encoded);
                    // 发送给客户端的数据
                    outputStream = response.getOutputStream();
    
                    byte[] buff = new byte[1024];
                    bis = new BufferedInputStream(new FileInputStream(file));
                    //office打开异常
    /*                int i = bis.read(buff);
                    while (i != -1) {
                        outputStream.write(buff, 0, buff.length);
                        outputStream.flush();
                        i = bis.read(buff);
                    }*/
                    //office打开正常,但是QQ浏览器下载会异常
                    int len = 0;
                    while ((len = bis.read(buff)) >= 0) {
                        outputStream.write(buff, 0, len);
                        outputStream.flush();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //关闭流
                    try {
                        if (bis != null) {
                            bis.close();
                        }
                        if (outputStream != null) {
                            outputStream.close();
                        }
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                    // 文件删除
                    file.delete();
                }
            }
        }
    }
    

    2.WordUtil(用于生成最终word)

    package com.bonc.huanghai.manage.util;
    
    import cn.afterturn.easypoi.word.WordExportUtil;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.springframework.util.Assert;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.Map;
    
    
    /**
     * @ClassName:WordUtil
     * @author:莫须有
     * @Description: 导出word 只支持docx
     * @create:2020/2/13 19:23
     * @Version1.0
     */
    public class WordUtil {
    
        /**
         * 导出word
         * <p>第一步生成替换后的word文件,只支持docx</p>
         * <p>第二步下载生成的文件</p>
         * <p>第三步删除生成的临时文件</p>
         * 模版变量中变量格式:{{foo}}
         *
         * @param templatePath word模板地址
         * @param temDir       生成临时文件存放地址
         * @param fileName     文件名
         * @param params       替换的参数
         */
        public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params) {
            Assert.notNull(templatePath, "模板路径不能为空");
            Assert.notNull(temDir, "临时文件路径不能为空");
            Assert.notNull(fileName, "导出文件名不能为空");
            Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");
            if (!temDir.endsWith("/")) {
                temDir = temDir + File.separator;
            }
            File dir = new File(temDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            try {
                XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
                String tmpPath = temDir + fileName;
                FileOutputStream fos = new FileOutputStream(tmpPath);
                doc.write(fos);
                fos.flush();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    package com.bonc.huanghai.manage.service.report.impl;
    
    import cn.afterturn.easypoi.entity.ImageEntity;
    import com.bonc.huanghai.manage.model.count.Count;
    import com.bonc.huanghai.manage.model.ticket.TicketInfo;
    import com.bonc.huanghai.manage.model.tourist.TouristOrigin;
    import com.bonc.huanghai.manage.util.DownReportUtil;
    import com.bonc.huanghai.manage.util.JfreeUtil;
    import com.bonc.huanghai.manage.util.WordUtil;
    import com.bonc.huanghai.manage.mapper.count.ITouristPortraitMapper;
    import com.bonc.huanghai.manage.mapper.count.LyricalCountMapper;
    import com.bonc.huanghai.manage.mapper.oa.TicketMapper;
    import com.bonc.huanghai.manage.service.report.ReportService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Service;
    
    import java.io.File;
    import java.math.BigDecimal;
    import java.text.DecimalFormat;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /**
     * @ClassName:ReportServiceImpl
     * @author:莫须有
     * @Description: 导出报表
     * @create:2020/3/2 15:47
     * @Version1.0
     */
    @Service
    @Primary
    public class ReportServiceImpl implements ReportService {
        private static final String PERCENT_SIGN = "%";
        private static final String TEM_DIR = "tjs/tjs-manage/src/main/resources/templates/download/";
        private static final String TEMPLATE_PATH = "templates/数据报告模板.docx";
        private static final String DOCX = ".docx";
        private static final String DATA_ERROR = "(暂无数据)";
        private static final String DATA_PICTURE_ERROR = "(图片中数据暂无)";
        private static final String DATA_FIGURE_ERROR = "0";
        private static final Integer WIDTH = 550;
        private static final Integer HEIGHT = 400;
    
    
        @Autowired
        TicketMapper ticketMapper;
        @Autowired
        ITouristPortraitMapper iTouristPortraitMapper;
        @Autowired
        LyricalCountMapper lyricalCountMapper;
    
        /**
         * 生成百分比
         * @param proportionDouble
         * @return
         */
        private String proportionInit(double proportionDouble) {
            String format = new DecimalFormat("0").format(BigDecimal.valueOf(proportionDouble).multiply(new BigDecimal(100)));
            String str = format + PERCENT_SIGN;
            return str;
        }
    
        /**
         * 导出景区数据分析报告
         * @param title
         * @param beginDate
         * @param endDate
         * @return
         */
        @Override
        public String downloadReport(String title, String beginDate, String endDate) {
    
            HashMap<String, Object> map = new HashMap<>(40);
            if (title == null || title.length() == 0){
                title = "景区_"+beginDate+"-"+endDate+"_数据分析报告";
            }
            //标题,起止时间
            map.put("title", title);
            map.put("beginDate", beginDate);
            map.put("endDate", endDate);
    
            // 获取当前时间
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy年MM月dd日");
            Date date = new Date();
            map.put("date", sdf.format(date));
    
            //游客画像分析
            //省内外游客客流量
            map.putAll(provincialSourceToReporttPic(beginDate, endDate));
            //国内游客画像,省外游客
            map.putAll(outofprovinceSourceRankingPic(beginDate, endDate));
            //国内游客画像,省内游客
            map.putAll(provincialSourceRankingPic(beginDate, endDate));
            //游客年龄段分布
            map.putAll(ageProportionPic(beginDate, endDate));
            //游客男女性别分布
            map.putAll(sexProportionPic(beginDate, endDate));
            //游客交通方式分析
            map.putAll(transportationProportionPic(beginDate, endDate));
            //游客消费潜力分析
            map.putAll(consumptionLevelPic(beginDate, endDate));
            //车辆来源分析
            map.putAll(carOriginPic(beginDate, endDate));
            //门票汇总分析
            map.putAll(ticketPic(beginDate, endDate));
            //舆情分析
            map.putAll(lyricalPic(beginDate, endDate));
    
            //导出word
            String fileName = title + DOCX;
            WordUtil.exportWord(TEMPLATE_PATH, TEM_DIR, fileName, map);
    
            //下载文件
            try {
                DownReportUtil.download(TEM_DIR + fileName, fileName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            File file = new File(TEM_DIR + fileName);
            // 文件删除
            if (file.isFile() && file.exists()) {
                file.delete();
            }
            return "OK";
        }
    
       /**
         * 游客画像分析
         * 省内外游客客流量
         *
         * @param beginDate
         * @param endDate
         * @return map (2)
         */
        private HashMap<String, Object> provincialSourceToReporttPic(String beginDate, String endDate) {
            HashMap<String, Object> map = new HashMap<>(2);
    
            //省内外+未知等的总游客数量
            int sumOfAllTourist = 0;
            try {
            /*
            存放进柱状图的数据集
             */
                List<Object[]> provincialSourceToReportPicData = new ArrayList<Object[]>();
            /*
            存放数据库取出的数据
             */
                List<TouristOrigin> provincialSourceToReport = iTouristPortraitMapper.provincialSourceToReport(beginDate, endDate);
            /*
            将数据库取出的数据放入柱状图的数据集
             */
                for (TouristOrigin data : provincialSourceToReport) {
                    if (data.getInProvince() == 0) {
                        provincialSourceToReportPicData.add(new Object[]{data.getCount(), "省外", data.getDate()});
                    }
                    if (data.getInProvince() == 1) {
                        provincialSourceToReportPicData.add(new Object[]{data.getCount(), "省内", data.getDate()});
                    }
                    sumOfAllTourist = sumOfAllTourist + data.getCount();
                }
                /*
                判断数据是否为空或0,若为空或零则直接当做异常处理
                 */
                if (provincialSourceToReport == null || provincialSourceToReport.size()==0 || sumOfAllTourist ==0) {
                    throw new Exception();
                }
            /*
            生成柱状图的图片
             */
                ImageEntity provincialSourceToReporttPic = JfreeUtil.stackedBarChart("省内外游客流量", "", "游客数量", provincialSourceToReportPicData, WIDTH, HEIGHT);
            /*
            放入文档对应的map集合中
             */
                map.put("provincialSourceToReporttPic", provincialSourceToReporttPic);
                map.put("游客总计", sumOfAllTourist);
            }catch (Exception e){
                e.printStackTrace();
                map.put("provincialSourceToReporttPic", DATA_PICTURE_ERROR);
                map.put("游客总计", DATA_FIGURE_ERROR);
            }
            return map;
        }
    

    相关文章

      网友评论

          本文标题:jfree+easypoi实现数据报表导出下载

          本文链接:https://www.haomeiwen.com/subject/slhmtktx.html