瀏覽代碼

fix 统计查询导出PDF

Administrator 1 年之前
父節點
當前提交
db77153a19

+ 49 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/statistics/StatisticsController.java

@@ -0,0 +1,49 @@
+package com.ruoyi.web.controller.statistics;
+
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.system.domain.member.MemberInfo;
+import com.ruoyi.system.domain.sqmy.SqmyUnitReply;
+import com.ruoyi.system.service.ISqmyInfoService;
+import com.ruoyi.system.service.IStatisticsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/3/18 13:54
+ * @Describe:
+ */
+@RestController
+@RequestMapping("/statistics")
+public class StatisticsController extends BaseController {
+    @Autowired
+    private IStatisticsService statisticsService;
+
+    /**
+     * 统计查询委员图形分析 界别
+     */
+    @PreAuthorize("@ss.hasPermi('statistics:boundary:find')")
+    @PostMapping("/boundary")
+    public AjaxResult boundary() {
+        AjaxResult boundary = statisticsService.boundary();
+        return AjaxResult.success(boundary);
+    }
+
+
+    /**
+     * 统计查询导出
+     */
+    @PreAuthorize("@ss.hasPermi('statistics:boundary:exportForm')")
+    @PostMapping("/exportForm")
+    public void exportForm(HttpServletResponse response, MemberInfo memberInfo) {
+        statisticsService.exportForm(response, memberInfo);
+    }
+}

+ 21 - 7
ruoyi-common/pom.xml

@@ -16,6 +16,20 @@
     </description>
 
     <dependencies>
+
+        <!--pdf导出-->
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13.3</version>
+        </dependency>
+        <!--pdf导出中文支持-->
+        <dependency>
+        <groupId>com.itextpdf</groupId>
+        <artifactId>itext-asian</artifactId>
+        <version>5.2.0</version>
+        </dependency>
+
         <!--阿里短信服务-->
         <dependency>
             <groupId>com.aliyun</groupId>
@@ -58,19 +72,19 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-  
+
         <!-- JSON工具类 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-        
+
         <!-- 动态数据源 -->
-		<dependency>
-			<groupId>com.baomidou</groupId>
-			<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
-			<version>3.5.2</version>
-		</dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>3.5.2</version>
+        </dependency>
 
         <!-- 阿里JSON解析器 -->
         <dependency>

+ 510 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/PDFUtil.java

@@ -0,0 +1,510 @@
+package com.ruoyi.common.utils;
+
+import com.itextpdf.text.*;
+import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfPCell;
+import com.itextpdf.text.pdf.PdfPTable;
+import com.itextpdf.text.pdf.PdfWriter;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/3/18 15:34
+ * @Describe:
+ */
+public class PDFUtil {
+    private static final Logger logger = LogManager.getLogger(PDFUtil.class);
+
+    /**
+     * fontSize_normal : (正文字体大小11号).
+     */
+    public static final float FONTSIZE_NORMAL = 11f;
+    /**
+     * fontSize_titile : (标题字体大小14号).
+     */
+    public static final float FONTSIZE_TITILE = 14f;
+    /**
+     * FONTSIZE_COVER : (封面字体大小32号).
+     */
+    public static final float FONTSIZE_COVER = 32f;
+
+    /**
+     * normalFont : (通用字体样式:宋体、11号).
+     */
+    private static Font normalFont = null;
+    /**
+     * titleFont : (通用标题字体样式:宋体、14号、加粗).
+     */
+    private static Font titleFont = null;
+    /**
+     * coverFont : (通用封面字体样式:宋体、28号、加粗).
+     */
+    private static Font coverFont = null;
+
+    /**
+     * 标题是否居中,true-居中、false-默认居左
+     */
+    private static final Boolean titleCenter = true;
+    /**
+     * getBaseFont : (获取可以解析中文的字体:使用宋体). <br/>
+     *
+     * @author
+     * @return
+     * @since JDK 1.8
+     */
+    public static BaseFont getBaseFontChinese()
+    {
+        try
+        {
+            // 宋体资源文件路径,可以从C://Windows//Fonts//simsun.ttc拷贝到相应目录下
+            URL path = PDFUtil.class.getResource("/config/fonts/simsun.ttc");
+            return BaseFont.createFont(path + ",0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
+
+            // 本地测试:使用windows自带的宋体文件
+            // return BaseFont.createFont("C://Windows//Fonts//simsun.ttc,0", BaseFont.IDENTITY_H, false);
+        }
+        catch (Exception e)
+        {
+            logger.error("设置字体样式失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * getNormalFont : (获取普通字体样式). <br/>
+     *
+     * @author
+     * @return
+     * @since JDK 1.8
+     */
+    public static Font getNormalFont()
+    {
+        if (normalFont == null)
+        {
+            BaseFont bfChinese = getBaseFontChinese();
+            normalFont = new Font(bfChinese, FONTSIZE_NORMAL, Font.NORMAL);
+        }
+        return normalFont;
+    }
+
+    /**
+     * getTitleFont : (获取标题通用字体). <br/>
+     *
+     * @author
+     * @return
+     * @since JDK 1.8
+     */
+    public static Font getTitleFont()
+    {
+        if (titleFont == null)
+        {
+            BaseFont bfChinese = getBaseFontChinese();
+            titleFont = new Font(bfChinese, FONTSIZE_TITILE, Font.BOLD);
+        }
+        return titleFont;
+    }
+
+    /**
+     * getTitleFont : (获取封面通用字体). <br/>
+     *
+     * @author
+     * @return
+     * @since JDK 1.8
+     */
+    public static Font getCoverFontFont()
+    {
+        if (coverFont == null)
+        {
+            BaseFont bfChinese = getBaseFontChinese();
+            coverFont = new Font(bfChinese, FONTSIZE_COVER, Font.BOLD);
+        }
+        return coverFont;
+    }
+
+    /**
+     * getfieldValue : (通过反射,根据方法名,执行方法,最终返回行结果的toString值). <br/>
+     *
+     * @author
+     * @param <T> 方法执行的入参
+     * @param object 对象
+     * @param methodName 方法名
+     * @param args 方法执行参数
+     * @since JDK 1.8
+     */
+    private static <T> String getfieldValue(T object, String methodName, Object... args)
+    {
+        try
+        {
+            Method method = object.getClass().getMethod(methodName);
+            Object value = method.invoke(object, args);
+            return value == null ? "" : value.toString();
+
+        }
+        catch (Exception e)
+        {
+            logger.error("getfieldValue error", e);
+            return "";
+        }
+    }
+
+    /**
+     * analysisPicBase64Info : (解析base64图片信息). <br/>
+     *
+     * @author
+     * @param picBase64Info 图片base64信息,或前台echart通过调用getDataURL()方法获取的图片信息
+     * @return 图片经过base64解码后的信息
+     * @since JDK 1.8
+     */
+    public static Element analysisPicBase64Info(String picBase64Info)
+    {
+        if (StringUtils.isEmpty(picBase64Info))
+        {
+            // 空段落
+            return new Paragraph();
+        }
+
+        // 1.获取图片base64字符串信息:若入参是通过前台echarts调用getDataURL()方法获取的,则该字符串包含逗号,且则逗号后面的内容才是图片的信息
+        String pictureInfoStr = picBase64Info.indexOf(",") == -1 ? picBase64Info : picBase64Info.split(",")[1];
+        // 2.将图片信息进行base64解密
+        byte[] imgByte = Base64.decodeBase64(pictureInfoStr);
+
+        // 对异常的数据进行处理
+        /**
+         * .图片的原始表达ascii码范围是0-255,
+         * .这里面有一些不可见的编码。然后为了图片正确传输才转成编码base64的0-63,
+         * .当从base64转成byte时,byte的范围是[-128,127],那么此时就会可能产生负数,而负数不是在ascii的范围里,所以需要转换一下
+         */
+        for (int i = 0; i < imgByte.length; i++)
+        {
+            if (imgByte[i] < 0)
+            {
+                imgByte[i] += 256;
+            }
+        }
+
+        try
+        {
+            return Image.getInstance(imgByte);
+        }
+        catch (Exception e)
+        {
+            logger.error("analysisPicBase64Info error", e);
+            return new Paragraph();
+        }
+    }
+
+    /**
+     * analysisPicBase64Info_batch : (批量解析base64加密的图片信息,生成Image对象). <br/>
+     *
+     * @author
+     * @param picBase64Infos 经过base64加密的图片信息
+     * @return
+     * @since JDK 1.8
+     */
+    public static List<Element> analysisPicBase64Info_batch(List<String> picBase64Infos)
+    {
+        List<Element> images = new ArrayList<Element>();
+        for (String li : picBase64Infos)
+        {
+            Element image = analysisPicBase64Info(li);
+            images.add(image);
+        }
+        return images;
+    }
+
+    /**
+     * createImage : (根据图片的base64加密文件创建pdf图片). <br/>
+     *
+     * @author
+     * @param picBase64Info base64加密后的图片信息(支持台echart通过调用getDataURL()方法获取的图片信息)
+     * @param title 段落标题
+     * @param percentX 图片缩放比例X轴
+     * @param percentY 图片缩放比例Y轴
+     * @param titleCenter 标题是否居中,true-居中、false-默认居左
+     * @return 返回图片段落
+     * @since JDK 1.8
+     */
+    public static Paragraph createImageFromEncodeBase64(String picBase64Info, String title, float percentX,
+                                                        float percentY, boolean titleCenter)
+    {
+        // 1.获取图片
+        Element element = analysisPicBase64Info(picBase64Info);
+        // 2.创建段落,并添加标题
+        Paragraph paragraph = new Paragraph(title, getTitleFont());
+        // 空行
+        paragraph.add(Chunk.NEWLINE);
+        paragraph.add(Chunk.NEWLINE);
+
+        if (!(element instanceof Image))
+        {
+            // 图片解析失败
+            return paragraph;
+        }
+
+        Image image = (Image) element;
+        // 3.设置图片缩放比例
+        image.scalePercent(percentX, percentY);
+
+        // 4.图片放入该段落
+        paragraph.add(image);
+
+        return paragraph;
+    }
+
+    /**
+     * createImageFromEncodeBase64_batch : (批量创建). <br/>
+     *
+     * @author
+     * @param picBase64Infos 图片base64加密后的信息(支持台echart通过调用getDataURL()方法获取的图片信息)
+     * @param titles 段落标题
+     * @param percentXs X轴缩放比例
+     * @param percentYs Y轴缩放比例
+     * @return
+     * @since JDK 1.8
+     */
+    public static Paragraph createImageFromEncodeBase64_batch(List<String> picBase64Infos, List<String> titles,
+                                                              List<Float> percentXs, List<Float> percentYs)
+    {
+        Paragraph paragraphs = new Paragraph();
+        for (int i = 0; i <= picBase64Infos.size(); i++)
+        {
+            Paragraph imagePara = createImageFromEncodeBase64(picBase64Infos.get(i), titles.get(i), percentXs.get(i),
+                    percentYs.get(i), titleCenter);
+            if (!imagePara.isEmpty())
+            {
+                paragraphs.add(imagePara);
+                // 空行
+                paragraphs.add(Chunk.NEWLINE);
+                paragraphs.add(Chunk.NEWLINE);
+            }
+        }
+        return paragraphs;
+    }
+
+    /**
+     * createTable : (创建table段落). <br/>
+     *
+     * @author
+     * @param <T>
+     * @param list 构建table的数据
+     * @param title 该段落取的名字
+     * @param methodNames 需要调用的方法名,用来获取单元格数据。通常是某个属性的get方法
+     * @return
+     * @since JDK 1.8
+     */
+    public static <T> Paragraph createTable(List<T> list, String title, String[] tableHead, List<String> methodNames)
+    {
+        return createTable(list, FONTSIZE_NORMAL, FONTSIZE_TITILE, title, tableHead, methodNames, false);
+    }
+
+    /**
+     * createTableByList : (创建table段落). <br/>
+     *
+     * @author
+     * @param <T>
+     * @param listData
+     * @param normalFontSize 正文字体大小
+     * @param titleFontSize 标题字体大小
+     * @param title 段落名称
+     * @param methodNames 获取表格属性的方法名
+     * @param b
+     * @return
+     * @since JDK 1.8
+     */
+    public static <T> Paragraph createTable(List<T> listData, float normalFontSize, float titleFontSize,
+                                            String title, String[] tableHead, List<String> methodNames, boolean b)
+    {
+        // 1.创建一个段落
+        Paragraph paragraph = new Paragraph(title, getTitleFont());
+        // 空行
+        paragraph.add(Chunk.NEWLINE);
+        paragraph.add(Chunk.NEWLINE);
+
+        // 3.创建一个表格
+        PdfPTable table = new PdfPTable(methodNames.size());// 列数
+        paragraph.add(table);
+
+        // 4.构造表头
+        for (String head : tableHead)
+        {
+            head = StringUtils.isEmpty(head) ? "" : head;
+            PdfPCell cell = new PdfPCell(new Paragraph(head, getNormalFont()));
+            cell.setBackgroundColor(
+                    new BaseColor(Integer.parseInt("124"), Integer.parseInt("185"), Integer.parseInt("252")));// 背景色
+            cell.setMinimumHeight(Float.parseFloat("15"));// 单元格最小高度
+            cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中
+            table.addCell(cell);
+        }
+
+        if (CollectionUtils.isEmpty(listData))
+        {
+            // 没有数据,添加一行空单元格,并返回
+            for (int i = 0; i < methodNames.size(); i++)
+            {
+                table.addCell(new Paragraph(" "));// 有一个空格,否则添加不了
+            }
+            return paragraph;
+        }
+
+        // 5.构造table数据
+        for (T li : listData)
+        {
+            for(String name : methodNames)
+            {
+                String valueStr = getfieldValue(li, name);
+                PdfPCell cell = new PdfPCell(new Paragraph(valueStr, getNormalFont()));
+                cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中
+                table.addCell(cell);
+            }
+        }
+        // 5.返回
+        return paragraph;
+    }
+
+    /**
+     * addToTable : (从段落中找到第一个table,向该table中追加数据). <br/>
+     * (). <br/>
+     *
+     * @author
+     * @param <T>
+     * @param paragraph
+     * @param listData
+     * @param methodNames
+     * @since JDK 1.8
+     */
+    public static <T> void addToTable(Paragraph paragraph, List<T> listData, List<String> methodNames)
+    {
+        for (Element ele : paragraph)
+        {
+            if (!(ele instanceof PdfPTable))
+            {
+                // 不是table元素,直接跳过
+                continue;
+            }
+
+            // 找到第一个table元素
+            PdfPTable table = (PdfPTable) ele;
+            for (T data : listData)
+            {
+                for (String name : methodNames)
+                {
+                    String valueStr = getfieldValue(data, name);
+                    PdfPCell cell = new PdfPCell(new Paragraph(valueStr, getNormalFont()));
+                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中
+                    table.addCell(cell);
+                }
+            }
+            break;
+        }
+
+    }
+
+    /**
+     * exportDocument : (生成并下载PDF文档). <br/>
+     * (). <br/>
+     *
+     * @author
+     * @param document 文档对象
+     * @param cover 封面:若不是null,则会先添加封面,并另起新页面添加段落
+     * @param paragraphs 需要组成PDF文件的段落
+     * @param response 请求的响应对象
+     * @param fileName 生成的文件名称,不需要加pdf后缀
+     * @since JDK 1.8
+     */
+    public static void exportDocument(Document document, Paragraph cover, List<Paragraph> paragraphs,
+                                      HttpServletResponse response, String fileName)
+    {
+        try (ServletOutputStream out = response.getOutputStream())
+        {
+            response.setContentType("application/binary;charset=UTF-8");
+            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName + ".pdf", "UTF-8"));
+
+            PdfWriter.getInstance(document, out);
+            // 打开文档
+            document.open();
+
+            if (cover != null)
+            {
+                document.add(cover);
+                // 起新页面
+                document.newPage();
+            }
+
+            StringBuilder errorMsg = new StringBuilder();
+            for (int i = 0; i < paragraphs.size(); i++)
+            {
+                try
+                {
+                    // 将段落添加到文档
+                    document.add(paragraphs.get(i));
+                    // 空行
+                    document.add(Chunk.NEWLINE);
+                    document.add(Chunk.NEWLINE);
+                }
+                catch (DocumentException e)
+                {
+                    errorMsg.append("PDF文件生成出错,请检查第:").append(i).append("个段落");
+                }
+            }
+
+            if (!StringUtils.isEmpty(errorMsg.toString()))
+            {
+                logger.error(errorMsg);
+            }
+
+            // 关闭文档
+            document.close();
+            out.flush();
+            out.close();
+        }
+        catch (Exception e)
+        {
+            logger.error("生成PDF文档并下载,出错:", e);
+        }
+
+    }
+
+    /**
+     * setDefaultIndentationLeft : (设置段落默认左边距). <br/>
+     *
+     * @author
+     * @param paragraph
+     * @since JDK 1.8
+     */
+    public static void setDefaultIndentationLeft(Paragraph paragraph)
+    {
+        paragraph.setIndentationLeft(Float.parseFloat("30"));
+    }
+
+    /**
+     * addBlankLine : (添加空行). <br/>
+     *
+     * @author
+     * @param paragraph 需要添加空行的段落
+     * @param lineNum 需要添加空行的个数
+     * @since JDK 1.8
+     */
+    public static void addBlankLine(Paragraph paragraph, int lineNum)
+    {
+        if (paragraph == null)
+        {
+            return;
+        }
+
+        for (int i = 0; i < lineNum; i++)
+        {
+            paragraph.add(Chunk.NEWLINE);
+        }
+    }
+}

+ 23 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/member/MemberInfo.java

@@ -71,7 +71,30 @@ public class MemberInfo extends BaseEntity
 
     /** 地址类型 1:领衔,2:附议 */
     private String type;
+    /**
+     * 柱状图base64编码
+     */
+    private String ele;
+    /**
+     * 饼状图base64编码
+     */
+    private String pie;
+
+    public String getEle() {
+        return ele;
+    }
 
+    public void setEle(String ele) {
+        this.ele = ele;
+    }
+
+    public String getPie() {
+        return pie;
+    }
+
+    public void setPie(String pie) {
+        this.pie = pie;
+    }
 
     public String getGrade() {
         return grade;

+ 49 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MemberInfoVoTwo.java

@@ -0,0 +1,49 @@
+package com.ruoyi.system.domain.vo;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/3/18 14:24
+ * @Describe:
+ */
+public class MemberInfoVoTwo {
+
+
+    /**
+     * 序号
+     */
+    private Long sort;
+    /**
+     * 界别
+     */
+    private String boundary;
+    /**
+     * 人数
+     */
+    private Integer num;
+
+    public Integer getNum() {
+        return num;
+    }
+
+    public void setNum(Integer num) {
+        this.num = num;
+    }
+
+    public String getBoundary() {
+        return boundary;
+    }
+
+    public void setBoundary(String boundary) {
+        this.boundary = boundary;
+    }
+
+
+
+    public Long getSort() {
+        return sort;
+    }
+
+    public void setSort(Long sort) {
+        this.sort = sort;
+    }
+}

+ 20 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/IStatisticsService.java

@@ -0,0 +1,20 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.system.domain.member.MemberInfo;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/3/18 13:55
+ * @Describe:
+ */
+public interface IStatisticsService {
+
+    /**
+     * 统计查询委员图形分析 界别
+     */
+    AjaxResult boundary();
+    void exportForm(HttpServletResponse response, MemberInfo memberInfo);
+}

+ 124 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StatisticsServiceImpl.java

@@ -0,0 +1,124 @@
+package com.ruoyi.system.service.impl;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.google.gson.JsonObject;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.Paragraph;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.common.utils.PDFUtil;
+import com.ruoyi.system.domain.member.MemberInfo;
+import com.ruoyi.system.domain.vo.MemberInfoVoTwo;
+import com.ruoyi.system.mapper.MemberInfoMapper;
+import com.ruoyi.system.mapper.SysDictDataMapper;
+import com.ruoyi.system.service.IStatisticsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/3/18 13:55
+ * @Describe:
+ */
+@Service
+public class StatisticsServiceImpl implements IStatisticsService {
+
+    @Autowired
+    private MemberInfoMapper memberInfoMapper;
+
+    @Autowired
+    private SysDictDataMapper dictDataMapper;
+
+    /**
+     * 统计查询委员图形分析 界别
+     */
+    @Override
+    public AjaxResult boundary() {
+        Map<String, Object> mapZ = new HashMap<>(4);
+        //查询界别字典值
+        List<SysDictData> dictDataList = dictDataMapper.selectDictDataByType("circles");
+        if (dictDataList != null && dictDataList.size() > 0) {
+            //根据委员界别分类统计
+            List<MemberInfo> memberInfoList = memberInfoMapper.selectMemberInfoList(new MemberInfo());
+            if (memberInfoList != null && memberInfoList.size() > 0) {
+                Map<String, List<MemberInfo>> memberInfoCollect = memberInfoList.stream().collect(Collectors.groupingBy(MemberInfo::getBoundary));
+                List<String> dictLabelList = new ArrayList<>();
+                List<Integer> dictValueList = new ArrayList<>();
+                List<MemberInfoVoTwo> memberInfoVoTwoList = new ArrayList<>();
+                List<JSONObject> jsonObjsList = new ArrayList<>();
+                for (SysDictData sysDictData : dictDataList) {
+                    JSONObject jsonObj = new JSONObject();
+                    MemberInfoVoTwo memberInfoVoTwo = new MemberInfoVoTwo();
+                    memberInfoVoTwo.setSort(sysDictData.getDictSort());
+                    String dictLabel = sysDictData.getDictLabel();
+                    String dictValue = sysDictData.getDictValue();
+                    jsonObj.put("name",dictLabel);
+                    memberInfoVoTwo.setBoundary(dictLabel);
+                    //柱状图
+                    dictLabelList.add(dictLabel);
+                    List<MemberInfo> memberInfoListV = memberInfoCollect.get(dictValue);
+                    //如果没这个界别就输入0
+                    if (memberInfoListV != null && memberInfoListV.size() > 0){
+                        dictValueList.add(memberInfoListV.size());
+                        memberInfoVoTwo.setNum(memberInfoListV.size());
+                        jsonObj.put("value",memberInfoListV.size());
+
+                    }else {
+                        dictValueList.add(0);
+                        memberInfoVoTwo.setNum(0);
+                        jsonObj.put("value",0);
+                    }
+                    memberInfoVoTwoList.add(memberInfoVoTwo);
+                    jsonObjsList.add(jsonObj);
+                }
+                mapZ.put("x",dictLabelList );
+                mapZ.put("y",dictValueList );
+                mapZ.put("pieData",jsonObjsList );
+                mapZ.put("total", memberInfoList.size());
+                mapZ.put("list", memberInfoVoTwoList);
+            }
+        }
+        return AjaxResult.success(mapZ);
+    }
+
+    /**
+     * 导出pdf
+     * @param response
+     */
+    @Override
+    public void exportForm(HttpServletResponse response, MemberInfo memberInfo) {
+        // 1.创建文档,设置文档页面大小,页边距
+        Document document = new Document(PageSize.A4, Float.parseFloat("0"), Float.parseFloat("5"),
+                Float.parseFloat("34"), Float.parseFloat("50"));
+
+        // 2.解析前台传来的echart图,生成pdf段落元素
+        Paragraph pictureEle = PDFUtil.createImageFromEncodeBase64(memberInfo.getEle(), "柱状统计图", Float.parseFloat("34"),
+                Float.parseFloat("50"), true);
+        Paragraph pictureElePie = PDFUtil.createImageFromEncodeBase64(memberInfo.getPie(), "柱状统计图", Float.parseFloat("34"),
+                Float.parseFloat("100"), true);
+
+        // 生成table表格段落(略去此处)
+        // Paragraph table1 = PDFUtil.createTable(xx略, "2、段落名称2", new String[]
+        //{ "数据a1", "数据a2", "数据a3" }, xx略);
+        // Paragraph table2 = PDFUtil.createTable(xx略, "3、段落名称3", xx略, xx略);
+        // Paragraph table3  = PDFUtil.createTable(xx略,"4、段落名称4", xx略, xx略);
+
+        // 将所有需要放到文档里的元素,汇总
+        List<Paragraph> paragraphs = new ArrayList<Paragraph>();
+        paragraphs.add(pictureEle);
+        //paragraphs.add(table1);
+        //paragraphs.add(table2);
+        //paragraphs.add(table3);
+
+        // 导出pdf文档:将paragraphs塞到document中,并下载document
+        PDFUtil.exportDocument(document, null, paragraphs, response, "报表");
+    }
+}