package com.pqs9200.controller.business;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.njcn.pojo.data.WaveSvg;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
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.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.njcn.enums.LogTypeEnum;
import com.njcn.mapper.advanced.RangeMapper;
import com.njcn.mapper.configuration.RptAssMapper;
import com.njcn.mapper.configuration.RptDataMapper;
import com.njcn.mapper.configuration.RptPloyMapper;
import com.njcn.pojo.advanced.EventAssObj;
import com.njcn.pojo.commons.DatePojo;
import com.njcn.pojo.commons.EventEigDetail;
import com.njcn.pojo.commons.EventInfoDetail;
import com.njcn.pojo.commons.HttpResult;
import com.njcn.pojo.commons.RedisDB;
import com.njcn.pojo.commons.ReportAreaPojo;
import com.njcn.pojo.commons.ReportMonitorPojo;
import com.njcn.pojo.commons.WaveData;
import com.njcn.pojo.commons.area.Area;
import com.njcn.pojo.commons.area.AreaGeneral;
import com.njcn.pojo.commons.area.Iec28;
import com.njcn.pojo.commons.area.Interval;
import com.njcn.pojo.commons.area.Voltage;
import com.njcn.pojo.commons.device.AnalyzeInfo;
import com.njcn.pojo.commons.device.DeviceValue;
import com.njcn.pojo.commons.device.EventCause;
import com.njcn.pojo.commons.device.EventChance;
import com.njcn.pojo.commons.device.EventDataList;
import com.njcn.pojo.commons.device.EventDensity;
import com.njcn.pojo.commons.device.EventTypeList;
import com.njcn.pojo.commons.device.LineInfo;
import com.njcn.pojo.configuration.RptPloy;
import com.njcn.pojo.data.EventDetail;
import com.njcn.pojo.data.LineMaps;
import com.njcn.pojo.user.Depts;
import com.njcn.pojo.wave.WaveDataDetail;
import com.njcn.service.advanced.RangeService;
import com.njcn.service.commons.IWaveService;
import com.njcn.service.configuration.DeviceService;
import com.njcn.service.configuration.ReportService;
import com.njcn.service.data.EventDetailService;
import com.njcn.service.log.UserLogDetailService;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.AppConfig;
import com.njcn.utils.ClearPathUtil;
import com.njcn.utils.InstantiateUtil;
import com.njcn.utils.PubUtils;
import com.njcn.utils.UserUtil;
import com.njcn.utils.redis.JedisManager;
import com.pqs9200.pojo.commons.device.DevMapInfo;
import com.pqs9200.service.area.IAreaService;
import com.pqs9200.service.data.IOverviewServer;
import com.pqs9200.utils.WordUtil;
import com.pqs9200.utils.WordUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;

import static java.lang.Float.parseFloat;

@Controller
@RequestMapping("report")
public class ReportController {
    @Resource
    private RptDataMapper rptDataMapper;

    @Resource
    private RptPloyMapper rptPloyMapper;

    @Resource
    private RptAssMapper rptAssMapper;

    @Resource
    private ReportService getreportInfo;

    @Autowired
    private ReportService reportService;

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IOverviewServer iOverviewServer;

    @Resource
    UserLogDetailService userLog;

    @Autowired
    private RangeMapper rangeMapper;

    @Autowired
    private RangeService rangeService;

    @Autowired
    private EventDetailService eventDetailService;

    @Autowired
    private IWaveService waveService;
    @Autowired
    private AppConfig appConfig;
    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(DeviceController.class);
    /**
     * 缓存每个方法查询的结果，缓存时间为半小时
     * <p>
     * key:方法名+参数值（参数为对象时，约定某个属性值）
     */
    @Autowired
    private JedisManager jedisManager;

    @Autowired
    private DeviceService deviceInfo;

    @Resource
    private UserUtil userUtil;

    @Autowired
    private UserLogDetailService userLogDetailService;

    private InstantiateUtil<JSONObject> instantiateUtil;
    private InstantiateUtil<JSONArray> jsonArrayInstantiateUtil;
    private InstantiateUtil<String> stringInstantiateUtil;

    public ReportController() {
        instantiateUtil = new InstantiateUtil<>();
        jsonArrayInstantiateUtil = new InstantiateUtil<>();
        stringInstantiateUtil = new InstantiateUtil<>();
    }

    /**
     * 获取模板引擎
     *
     * @return
     */
    @PostMapping("monitorTemplate")
    @ResponseBody
    public HttpResult monitorTemplate() {
        HttpResult result;
        List<RptPloy> datas;
        datas = reportService.getTemplate(Integer.valueOf(0));
        if (CollectionUtils.isEmpty(datas)) {
            result = PubUtils.assignmentResult(null, 500, "沒有对应的模板");
        } else {
            result = PubUtils.assignmentResult(datas, 200, "获取模板成功");
        }
        return result;
    }

    @PostMapping("monitor")
    @ResponseBody
    public HttpResult monitor(HttpServletRequest request, String startTime, String endTime, String lineIndex, String lineName, boolean jcdxq,
                              boolean zjsjlb, boolean zjsjssbx, boolean zjmdbg, boolean zjmdtx, boolean zjsjditic, boolean zjsjdf47, boolean glfbzjfz,
                              boolean glfbcxsj, boolean yftjbg, boolean yftjtx, boolean zjyybg, boolean zjyytx, boolean zjlxbg, boolean zjlxtx) throws Exception {
        HttpResult result;
        List<Object> reList = new ArrayList<>();
        ReportMonitorPojo reportMonitorPojo = getMonitorChoose(request, startTime, endTime, lineIndex, lineName, jcdxq, zjsjlb, zjsjssbx, zjmdbg, zjmdtx, zjsjditic, zjsjdf47, glfbzjfz, glfbcxsj, yftjbg, yftjtx, zjyybg, zjyytx, zjlxbg, zjlxtx);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(reportMonitorPojo.getStartTime(), reportMonitorPojo.getEndTime(), "monitor");
        String userIndex = TokenManager.getUserId();
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return result;
        }
        try {
            /* 监测点详情数据获取 */
            LineInfo lineInfo;
            if (reportMonitorPojo.isJcdxq()) {
                lineInfo = deviceInfo.getDeviceInfo(Long.valueOf(reportMonitorPojo.getLineIndex()));
                JSONObject lineO = JSONObject.fromObject(lineInfo);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "lineInfo", instantiateUtil.stringInstantiate(lineO), RedisDB.SHORT_TIME);
            }
            /* 暂降事件列表 */
            List<AnalyzeInfo> analyzeInfos = null;
            if (reportMonitorPojo.isZjsjlb()) {
                analyzeInfos = deviceInfo.queryanalyzeinfo(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                JSONArray anArray = JSONArray.fromObject(analyzeInfos);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "analyzeInfos", jsonArrayInstantiateUtil.stringInstantiate(anArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降事件波形 */
            List<List> arry = new ArrayList<>();
            int waveNum = 0;
            if (reportMonitorPojo.isZjsjssbx()) {
                List<AnalyzeInfo> analyzeInfo = null;
                analyzeInfo = deviceInfo.queryanalyzeinfo(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                analyzeInfo = analyzeInfo.stream().filter(temp ->
                        parseFloat(temp.getPersisttime()) < 2.0
                ).collect(Collectors.toList());
                for (int i = 0; i < analyzeInfo.size(); i++) {
                    if (Integer.parseInt(analyzeInfo.get(i).getFileFlag()) == 0) {
                        analyzeInfo.remove(i);
                    }
                }
                if (analyzeInfo.size() > 10) {
                    waveNum = 10;
                } else {
                    waveNum = analyzeInfo.size();
                }
                for (int i = 0; i < waveNum; i++) {
                    List<WaveSvg> shunS = new ArrayList<>();
                    WaveData waveData = waveService.getWavedata(analyzeInfo.get(i).getEventDetailIndex(), 1);
                    if (waveData != null) {
                        if (waveData.getiPhasic() > 0) {
                            //数据筛选,如果是双路电压的话，会存在2个波形数据
                            List<WaveDataDetail> waveDataDetails = waveService.filteWaveData(waveData);
                            if (waveData.getSunData().size() == 0) {

                            } else {
                                String time = waveData.getTime();
                                String title = "监测点名称：" + waveData.getLineName() + " 发生时刻：" + time + "特征幅值：" + waveData.getEventValue() + " 持续时间：" + waveData.getPersistTime() + "s";
                                if (waveDataDetails.size() == 1) {
                                    shunS.add(waveService.createShunSTitle(title, waveDataDetails.get(0)));
                                } else {
                                    shunS.add(waveService.createShunSTitle(title, waveDataDetails.get(0)));
                                    for (int n = 1; n < waveDataDetails.size(); n++) {
                                        shunS.add(waveService.createShunS(waveDataDetails.get(n)));
                                    }
                                }

                            }
                            arry.add(shunS);
                        }
                    }
                }
            }
            /* 暂降密度数据获取 */
            List<EventDensity> eventDensities = new ArrayList<>();
            if (reportMonitorPojo.isZjmdtx()) {
                eventDensities = deviceInfo.getEventDensity(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
            }
            List<List> eventDisdip;
            List<List> ec411;
            List<List> ec28;
            if (reportMonitorPojo.isZjmdbg()) {
                eventDisdip = deviceInfo.getEventDisdip(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                ec411 = deviceInfo.getIEC411(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                ec28 = deviceInfo.getIEC28(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                JSONArray evArray = JSONArray.fromObject(eventDisdip);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventDisdip", jsonArrayInstantiateUtil.stringInstantiate(evArray),
                        RedisDB.SHORT_TIME);
                JSONArray ec4Array = JSONArray.fromObject(ec411);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "ec411", jsonArrayInstantiateUtil.stringInstantiate(ec4Array), RedisDB.SHORT_TIME);
                JSONArray ec2Array = JSONArray.fromObject(ec28);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "ec28", jsonArrayInstantiateUtil.stringInstantiate(ec2Array), RedisDB.SHORT_TIME);
            }
            /* 暂降事件点图 */
            List<EventDataList> eventDataLists = new ArrayList<>();
            if (reportMonitorPojo.isZjsjditic() || reportMonitorPojo.isZjsjdf47()) {
                eventDataLists = deviceInfo.getEventDataList(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
            }
            /* 概率分布 */
            EventChance eventChance = new EventChance();
            if (reportMonitorPojo.isGlfbzjfz() || reportMonitorPojo.isGlfbcxsj()) {
                eventChance = deviceInfo.getEventChance(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
            }
            /* 月份统计图 */
            List<Interval> intervals = new ArrayList<>();
            if (reportMonitorPojo.isYftjbg() || reportMonitorPojo.isYftjtx()) {
                intervals = deviceInfo.getEventTime(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                JSONArray inArray = JSONArray.fromObject(intervals);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "intervals", jsonArrayInstantiateUtil.stringInstantiate(inArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降原因 */
            List<EventCause> eventCauses = new ArrayList<>();
            if (reportMonitorPojo.isZjyybg() || reportMonitorPojo.isZjyytx()) {
                eventCauses = deviceInfo.getEventCause(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                JSONArray caArray = JSONArray.fromObject(eventCauses);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventCauses", jsonArrayInstantiateUtil.stringInstantiate(caArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降类型 */
            List<EventTypeList> eventTypeLists = new ArrayList<>();
            if (reportMonitorPojo.isZjlxbg() || reportMonitorPojo.isZjlxtx()) {
                eventTypeLists = deviceInfo.getEventType(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportMonitorPojo.getLineIndex());
                JSONArray tyArray = JSONArray.fromObject(eventTypeLists);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventTypeLists", jsonArrayInstantiateUtil.stringInstantiate(tyArray),
                        RedisDB.SHORT_TIME);
            }
            JSONObject reportPojo = JSONObject.fromObject(reportMonitorPojo);
            String key = TokenManager.getUserId() + "reportPojo";
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, key, instantiateUtil.stringInstantiate(reportPojo), RedisDB.SHORT_TIME);
            /* 将前台需要画图的数据返回 */
            reList.add(eventDensities);
            reList.add(eventDataLists);
            reList.add(eventChance);
            reList.add(intervals);
            reList.add(eventCauses);
            reList.add(eventTypeLists);
            reList.add(arry);
            result = PubUtils.assignmentResult(reList, 200, "获取监测点图表数据成功");
        } catch (Exception e) {
            logger.error("获取监测点图表数据异常,异常为：" + e.toString());
            result = PubUtils.assignmentResult(null, 500, "获取监测点图表数据异常");
        }

        return result;
    }

    /**
     * 根据用户页面的选择，指定我们需要查询的数据
     *
     * @param request 请求
     */
    private ReportMonitorPojo getMonitorChoose(HttpServletRequest request, String startTime, String endTime, String lineIndex, String lineName, boolean jcdxq,
                                               boolean zjsjlb, boolean zjsjssbx, boolean zjmdbg, boolean zjmdtx, boolean zjsjditic, boolean zjsjdf47, boolean glfbzjfz,
                                               boolean glfbcxsj, boolean yftjbg, boolean yftjtx, boolean zjyybg, boolean zjyytx, boolean zjlxbg, boolean zjlxtx) {
        ReportMonitorPojo reportMonitorPojo = new ReportMonitorPojo();
        reportMonitorPojo.setJcdxq(Boolean.valueOf(jcdxq));
        reportMonitorPojo.setZjsjlb(Boolean.valueOf(zjsjlb));
        reportMonitorPojo.setZjsjssbx(Boolean.valueOf(zjsjssbx));
        reportMonitorPojo.setZjmdbg(Boolean.valueOf(zjmdbg));
        reportMonitorPojo.setZjmdtx(Boolean.valueOf(zjmdtx));
        reportMonitorPojo.setZjsjditic(Boolean.valueOf(zjsjditic));
        reportMonitorPojo.setZjsjdf47(Boolean.valueOf(zjsjdf47));
        reportMonitorPojo.setGlfbzjfz(Boolean.valueOf(glfbzjfz));
        reportMonitorPojo.setGlfbcxsj(Boolean.valueOf(glfbcxsj));
        reportMonitorPojo.setYftjbg(Boolean.valueOf(yftjbg));
        reportMonitorPojo.setYftjtx(Boolean.valueOf(yftjtx));
        reportMonitorPojo.setZjyybg(Boolean.valueOf(zjyybg));
        reportMonitorPojo.setZjyytx(Boolean.valueOf(zjyytx));
        reportMonitorPojo.setZjlxbg(Boolean.valueOf(zjlxbg));
        reportMonitorPojo.setZjlxtx(Boolean.valueOf(zjlxtx));
        reportMonitorPojo.setStartTime(startTime);
        reportMonitorPojo.setEndTime(endTime);
        reportMonitorPojo.setLineIndex(lineIndex);
        reportMonitorPojo.setLineName(lineName);
        return reportMonitorPojo;

    }

    @PostMapping("exportReport")
    @ResponseBody
    public String exportReport(HttpServletRequest request, String densityImage, String iticImage, String f47Image, String eventValueImage,
                               String persisttimeImage, String shunSImg, String timeImage, String causeImage, String typeImage, String startTime, String endTime) throws Exception {
        String userIndex = TokenManager.getUserId();
        JSONObject jsonObject = instantiateUtil.deInstantiate(instantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex,
                TokenManager.getUserId() + "reportPojo")));
        ReportMonitorPojo reportMonitorPojo = (ReportMonitorPojo) JSONObject.toBean(jsonObject,
                ReportMonitorPojo.class);
        // 需要展示的图
        if (reportMonitorPojo.isZjmdtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "densityImage", stringInstantiateUtil.stringInstantiate(densityImage), RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isZjsjssbx()) {
            if (!shunSImg.equals("[]")) {
                JSONArray jsonArray = JSONArray.fromObject(shunSImg);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "shunSImage", jsonArrayInstantiateUtil.stringInstantiate(jsonArray), RedisDB.SHORT_TIME);
            } else {
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "shunSImage", jsonArrayInstantiateUtil.stringInstantiate(null), RedisDB.SHORT_TIME);
            }
        }
        if (reportMonitorPojo.isZjsjditic()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "iticImage", stringInstantiateUtil.stringInstantiate(iticImage), RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isZjsjdf47()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "f47Image", stringInstantiateUtil.stringInstantiate(f47Image), RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isGlfbzjfz()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventValueImage", stringInstantiateUtil.stringInstantiate(eventValueImage),
                    RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isGlfbcxsj()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "persisttimeImage", stringInstantiateUtil.stringInstantiate(persisttimeImage),
                    RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isYftjtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "timeImage", stringInstantiateUtil.stringInstantiate(timeImage), RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isZjyytx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "causeImage", stringInstantiateUtil.stringInstantiate(causeImage), RedisDB.SHORT_TIME);
        }
        if (reportMonitorPojo.isZjlxtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "typeImage", stringInstantiateUtil.stringInstantiate(typeImage), RedisDB.SHORT_TIME);
        }
        userLogDetailService.saveUserLog(TokenManager.getToken().getUserIndex(), TokenManager.getToken().getLoginName(),
                "生成监测点报告", "成功", appConfig.getSystemFlag(), PubUtils.getIpAddr(request),
                LogTypeEnum.BUSSINESS.toString(), 0);
        return "success";
    }

    @GetMapping("downMonitorReport")
    public void downMonitorReport(HttpServletResponse response, HttpServletRequest request, String name) throws Exception {
        String userIndex = TokenManager.getUserId();
        JSONObject jsonObject = instantiateUtil.deInstantiate(instantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex,
                TokenManager.getUserId() + "reportPojo")));
        jedisManager.hdel(RedisDB.SHORT_TIME_QUERY, userIndex, TokenManager.getUserId() + "reportPojo");
        ReportMonitorPojo reportMonitorPojo = (ReportMonitorPojo) JSONObject.toBean(jsonObject,
                ReportMonitorPojo.class);
        int one = 1;
        // 开始做文档
        XWPFDocument document = new XWPFDocument();
        // 设定标题格式
        WordUtils.setHeadingStyle(document);
        // 添加标题
        XWPFParagraph titleParagraph = WordUtils.getCenterParagraph(document);
        WordUtils.addLine(titleParagraph, 11);
        // 设置段落居中
        XWPFRun titleParagraphRun = titleParagraph.createRun();
        Depts deptTmp = userUtil.getCurrentDept();
        String titlename = deptTmp.getDeptsName();
        WordUtils.addParagraph(titleParagraphRun, "宋体", 15, "000000", titlename, true);
        WordUtils.addLine(titleParagraph, 3);
        XWPFRun titleParagraphBigRun = titleParagraph.createRun();
        WordUtils.addParagraph(titleParagraphBigRun, "宋体", 36, "000000", "电压暂降事件分析报告", true);
        WordUtils.addLine(titleParagraph, 19);
        XWPFRun titleParagraphDateRun = titleParagraph.createRun();
        WordUtils.addParagraph(titleParagraphDateRun, "宋体", 14, "000000", "日期：" + WordUtils.getRightNow(), true);
        titleParagraph.setPageBreak(true);
        // 段落
        XWPFParagraph statisticsParagraph = WordUtils.getCenterParagraph(document);
        // 段前分页
        statisticsParagraph.setPageBreak(true);
        XWPFRun statisticsRun = statisticsParagraph.createRun();
        WordUtils.addParagraph(statisticsRun, "宋体", 24, "000000", "电压暂降事件分析报告", false);
        createTitle(document, "1. 引言", "标题 1", 0, 15);
        XWPFParagraph introductionContentParagraph = WordUtils.getLeftParagraph(document);
        // 首行缩进---段落
        introductionContentParagraph.setIndentationFirstLine(200);
        XWPFRun introductionContentRun = introductionContentParagraph.createRun();
        WordUtils.addParagraph(introductionContentRun, "宋体", 11, "000000", "对所选中区间内电压暂降事件进行分析，能够直观清晰查看相应的暂降事件信息。",
                false);
        createTitle(document, "2. 报告分析对象", "标题 1", 0, 15);
        XWPFParagraph objectContentParagraph = WordUtils.getLeftParagraph(document);
        objectContentParagraph.setIndentationFirstLine(200);
        XWPFRun objectContentRun = objectContentParagraph.createRun();
        WordUtils.addParagraph(objectContentRun, "宋体", 11, "000000", reportMonitorPojo.getLineName(), false);
        createTitle(document, "3. 报告分析时间", "标题 1", 0, 15);
        XWPFParagraph timeContentParagraph = WordUtils.getLeftParagraph(document);
        timeContentParagraph.setIndentationFirstLine(200);
        XWPFRun timeContentRun = timeContentParagraph.createRun();
        WordUtils.addParagraph(timeContentRun, "宋体", 11, "000000",
                reportMonitorPojo.getStartTime() + " 至 " + reportMonitorPojo.getEndTime(), false);
        createTitle(document, "4. 汇总信息", "标题 1", 0, 15);
        /* 填充监测点详情 */
        if (reportMonitorPojo.isJcdxq()) {
            createTitle(document, "4." + one + " 监测点信息", "标题 2", 200, 11);
            // 监测点信息
            XWPFTable monitorInfo = createTable(document);
            XWPFParagraph monitorInfoExcelParagraph = WordUtils.getCenterParagraph(document);
            LineInfo lineInfo;
            JSONObject jo = instantiateUtil.deInstantiate(instantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "lineInfo")));
            lineInfo = (LineInfo) JSONObject.toBean(jo, LineInfo.class);
            // 表格第一行
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, true, "项目", "描述");
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "监测点名称", lineInfo.getName());
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "电压等级", lineInfo.getScale());
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "PT变比", lineInfo.getPT());
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "CT变比", lineInfo.getCT());
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "协议容量",
                    String.valueOf(lineInfo.getXYCMP()));
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "基准容量",
                    String.valueOf(lineInfo.getJZCMP()));
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "设备容量",
                    String.valueOf(lineInfo.getDEVCMP()));
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "最小短路容量",
                    String.valueOf(lineInfo.getDLCMP()));
            insertRow(document, monitorInfo, monitorInfoExcelParagraph, false, "接线方式", lineInfo.getPttype());
            one++;
        }
        /* 暂降事件列表 */
        List<AnalyzeInfo> analyzeInfos = null;
        if (reportMonitorPojo.isZjsjlb()) {
            createTitle(document, "4." + one + " 暂降事件列表", "标题 2", 200, 11);
            XWPFTable sum = createTable(document);
            XWPFParagraph sumExcelParagraph = WordUtils.getCenterParagraph(document);
            JSONArray ja = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "analyzeInfos")));
            analyzeInfos = (List<AnalyzeInfo>) JSONArray.toCollection(ja, AnalyzeInfo.class);
            insertRow(document, sum, sumExcelParagraph, true, "序号", "暂降发生时刻", "暂降幅值(%)", "持续时间(s)", "暂降类型", "暂降原因",
                    "严重度");
            if (analyzeInfos.isEmpty()) {
                insertRow(document, sum, sumExcelParagraph, false, "", "", "", "", "", "", "");
            } else {
                for (int i = 0; i < analyzeInfos.size(); i++) {
                    insertRow(document, sum, sumExcelParagraph, false, String.valueOf(i + 1),
                            analyzeInfos.get(i).getTime(), analyzeInfos.get(i).getEventvaule(),
                            analyzeInfos.get(i).getPersisttime(), analyzeInfos.get(i).getType(),
                            analyzeInfos.get(i).getReason(), String.valueOf(analyzeInfos.get(i).getYzd()));
                }
            }
            one++;
        }
        /* 暂降事件波形 */
        if (reportMonitorPojo.isZjsjssbx()) {
            createTitle(document, "4." + one + " 暂降事件图形", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isZjsjssbx()) {
                List<AnalyzeInfo> analyzeInfo = null;
                JSONArray ja = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "analyzeInfos")));
                analyzeInfo = (List<AnalyzeInfo>) JSONArray.toCollection(ja, AnalyzeInfo.class);
                for (int i = 0; i < analyzeInfo.size(); i++) {
                    if (Integer.parseInt(analyzeInfo.get(i).getFileFlag()) == 0) {
                        analyzeInfo.remove(i);
                    }
                }
                JSONArray shunSImages = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "shunSImage")));
                if (shunSImages != null) {
                    for (int i = 0; i < shunSImages.size(); i++) {
                        if (Integer.parseInt(analyzeInfo.get(i).getFileFlag()) == 1) {
                            createTitle(document, "事件" + (i + 1) + ":" + analyzeInfo.get(i).getTime(), "标题 3", 400, 11);
                            List<String> shunSImage;
                            shunSImage = (List<String>) JSONArray.toCollection((JSONArray) shunSImages.get(i));
                            for (int j = 0; j < shunSImage.size(); j++) {
                                createPic(document, shunSImage.get(j), "暂降事件图形");
                            }
                        }
                    }

                } else {
                    if (analyzeInfos.size() > 10) {
                        two = 10;
                    } else {
                        two = analyzeInfos.size();
                    }
                    for (int i = 0; i < two; i++) {
                        if (Integer.parseInt(analyzeInfos.get(i).getFileFlag()) == 1) {
                            createTitle(document, "事件" + (i + 1) + ":" + analyzeInfos.get(i).getTime() + "(未找到波形文件)", "标题 3", 400, 11);
                        }
                    }
                }

            }
            one++;
        }
        /* 暂降事件点图 */
        if (reportMonitorPojo.isZjsjditic() || reportMonitorPojo.isZjsjdf47()) {
            createTitle(document, "4." + one + " 暂降事件点图", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isZjsjditic()) {
                createTitle(document, "4." + one + "." + two + " ITIC曲线", "标题 3", 400, 11);
                String iticImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "iticImage")));
                createPic(document, iticImage, "ITIC曲线");
                two++;
            }
            if (reportMonitorPojo.isZjsjdf47()) {
                createTitle(document, "4." + one + "." + two + " F47曲线", "标题 3", 400, 11);
                String f47Image = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "f47Image")));
                createPic(document, f47Image, "F47曲线");
            }
            one++;
        }
        /* 暂降密度 */
        if (reportMonitorPojo.isZjmdtx() || reportMonitorPojo.isZjmdbg()) {
            createTitle(document, "4." + one + " 暂降密度", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isZjmdtx()) {
                createTitle(document, "4." + one + "." + two + " 暂降密度点图", "标题 3", 400, 11);
                String densityImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "densityImage")));
                createPic(document, densityImage, "暂降密度点图");
                two++;
            }
            if (reportMonitorPojo.isZjmdbg()) {
                createTitle(document, "4." + one + "." + two + " DISDIP表格:国际发配电联盟(UNIPEDE)", "标题 3", 400, 11);
                XWPFTable disdip = createTable(document);
                XWPFParagraph disdipExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> eventDisdip;
                JSONArray arrayeventDisdip = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventDisdip")));
                eventDisdip = (List<List>) JSONArray.toCollection(arrayeventDisdip, ArrayList.class);
                insertRow(document, disdip, disdipExcelParagraph, true, "剩余电压", "20ms", "100ms", "500ms", "1s", "3s",
                        "20s", "60s", "180s");
                if (eventDisdip.isEmpty()) {
                    insertRow(document, disdip, disdipExcelParagraph, false, "", "", "", "", "", "", "", "", "");
                } else {
                    for (List list : eventDisdip) {
                        insertRow(document, disdip, disdipExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString(),
                                list.get(7).toString(), list.get(8).toString());
                    }
                }
                two++;
                createTitle(document, "4." + one + "." + two + " IEC 61000-4-11:(用电终端的电压暂降抗度)", "标题 3", 400, 11);
                XWPFTable ec411Table = createTable(document);
                XWPFParagraph ec411TableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> ec411;
                JSONArray arrayec411 = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "ec411")));
                ec411 = (List<List>) JSONArray.toCollection(arrayec411, ArrayList.class);
                insertRow(document, ec411Table, ec411TableExcelParagraph, true, "剩余电压", "10~20ms", "20~100ms",
                        "0.1~0.2s", "0.2~0.5s", "0.5~1s", ">1s");
                if (ec411.isEmpty()) {
                    insertRow(document, ec411Table, ec411TableExcelParagraph, false, "", "", "", "", "", "", "");
                } else {
                    for (List list : ec411) {
                        insertRow(document, ec411Table, ec411TableExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString());
                    }
                }
                two++;
                createTitle(document, "4." + one + "." + two + " IEC 61000-2-8:(公共电网电压暂降测量统计)", "标题 3", 400, 11);
                XWPFTable ec28Table = createTable(document);
                XWPFParagraph ec28TableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> ec28;
                JSONArray arrayec28 = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "ec28")));
                ec28 = (List<List>) JSONArray.toCollection(arrayec28, ArrayList.class);
                insertRow(document, ec28Table, ec28TableExcelParagraph, true, "剩余电压", "0.02~0.1s", "0.1~0.25s",
                        "0.25~0.5s", "0.5~1s", "1~3s", "3~20s", "20~60s", "60~180s");
                if (ec28.isEmpty()) {
                    insertRow(document, ec28Table, ec28TableExcelParagraph, false, "", "", "", "", "", "", "", "", "");
                } else {
                    for (List list : ec28) {
                        insertRow(document, ec28Table, ec28TableExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString(),
                                list.get(7).toString(), list.get(8).toString());
                    }
                }
            }
            one++;
        }
        /* 概率分布 */
        if (reportMonitorPojo.isGlfbcxsj() || reportMonitorPojo.isGlfbzjfz()) {
            createTitle(document, "4." + one + " 暂降幅值概率分布图", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isGlfbzjfz()) {
                createTitle(document, "4." + one + "." + two + " 暂降幅值的概率分函数", "标题 3", 400, 11);
                String eventValueImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventValueImage")));
                createPic(document, eventValueImage, "暂降幅值的概率分布函数");
                two++;
            }
            if (reportMonitorPojo.isGlfbcxsj()) {
                createTitle(document, "4." + one + "." + two + " 持续时间的概率分函数", "标题 3", 400, 11);
                String persisttimeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "persisttimeImage")));
                createPic(document, persisttimeImage, "持续时间的概率分函数");
            }
            one++;
        }
        /* 月份统计 */
        if (reportMonitorPojo.isYftjtx() || reportMonitorPojo.isYftjbg()) {
            createTitle(document, "4." + one + " 月份统计", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isYftjtx()) {
                createTitle(document, "4." + one + "." + two + " 月份统计图", "标题 3", 400, 11);
                String timeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "timeImage")));
                createPic(document, timeImage, "月份统计图");
                two++;
            }
            if (reportMonitorPojo.isYftjbg()) {
                createTitle(document, "4." + one + "." + two + " 月份统计表格", "标题 3", 400, 11);
                XWPFTable intervalsTable = createTable(document);
                XWPFParagraph intervalsTableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<Interval> intervals;
                JSONArray arrayintervals = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "intervals")));
                intervals = (List<Interval>) JSONArray.toCollection(arrayintervals, Interval.class);
                insertRow(document, intervalsTable, intervalsTableExcelParagraph, true, "月份", "电压暂降次数");
                if (intervals.isEmpty()) {
                    insertRow(document, intervalsTable, intervalsTableExcelParagraph, false, "", "");
                } else {
                    for (Interval interval : intervals) {
                        insertRow(document, intervalsTable, intervalsTableExcelParagraph, false, interval.getMonth(),
                                String.valueOf(interval.getTimes()));
                    }
                }
            }
            one++;
        }
        /* 原因统计 */
        if (reportMonitorPojo.isZjyytx() || reportMonitorPojo.isZjyybg()) {
            createTitle(document, "4." + one + " 原因统计", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isZjyytx()) {
                createTitle(document, "4." + one + "." + two + " 原因统计图", "标题 3", 400, 11);
                String causeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "causeImage")));
                createPic(document, causeImage, "原因统计图");
                two++;
            }
            if (reportMonitorPojo.isZjyybg()) {
                createTitle(document, "4." + one + "." + two + " 原因统计表格", "标题 3", 400, 11);
                XWPFTable causeTable = createTable(document);
                XWPFParagraph causeTableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<EventCause> eventCauses;
                JSONArray arrayeventCauses = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventCauses")));
                eventCauses = (List<EventCause>) JSONArray.toCollection(arrayeventCauses, EventCause.class);
                insertRow(document, causeTable, causeTableExcelParagraph, true, "暂降原因", "电压暂降次数");
                if (eventCauses.isEmpty()) {
                    insertRow(document, causeTable, causeTableExcelParagraph, false, "", "");
                } else {
                    for (EventCause eventCause : eventCauses) {
                        insertRow(document, causeTable, causeTableExcelParagraph, false, eventCause.getCause(),
                                String.valueOf(eventCause.getCount()));
                    }
                }
            }
            one++;
        }
        /* 类型统计 */
        if (reportMonitorPojo.isZjlxtx() || reportMonitorPojo.isZjlxbg()) {
            createTitle(document, "4." + one + " 类型统计", "标题 2", 200, 11);
            int two = 1;
            if (reportMonitorPojo.isZjlxtx()) {
                createTitle(document, "4." + one + "." + two + " 类型统计图", "标题 3", 400, 11);
                String typeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "typeImage")));
                createPic(document, typeImage, "类型统计图");
                two++;
            }
            if (reportMonitorPojo.isZjlxbg()) {
                createTitle(document, "4." + one + "." + two + " 类型统计表格", "标题 3", 400, 11);
                XWPFTable typeTable = createTable(document);
                XWPFParagraph typeTableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<EventTypeList> eventTypeLists = new ArrayList();
                JSONArray arrayeventTypes = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventTypeLists")));
                eventTypeLists = (List<EventTypeList>) JSONArray.toCollection(arrayeventTypes, EventTypeList.class);
                insertRow(document, typeTable, typeTableExcelParagraph, true, "暂降类型", "电压暂降次数");
                if (eventTypeLists.isEmpty()) {
                    insertRow(document, typeTable, typeTableExcelParagraph, false, "", "");
                } else {
                    for (EventTypeList eventTypeList : eventTypeLists) {
                        insertRow(document, typeTable, typeTableExcelParagraph, false, eventTypeList.getType(),
                                String.valueOf(eventTypeList.getCount()));
                    }
                }
            }
        }
        OutputStream out;
        try {
            response.setContentType("application/force-download");// 设置强制下载不打开
            String agent = request.getHeader("User-Agent").toUpperCase(); // 获得浏览器信息并转换为大写
            if (agent.indexOf("MSIE") > 0 || (agent.indexOf("GECKO") > 0 && agent.indexOf("RV:11") > 0)) { // IE浏览器和Edge浏览器
                name = URLEncoder.encode(name, "UTF-8");
            } else { // 其他浏览器
//                name = new String(name.getBytes("UTF-8"), "iso-8859-1");
                name = URLEncoder.encode(name, "UTF-8");
            }
            response.addHeader("Content-Disposition", "attachment;fileName=" + name + ".docx");// 设置文件名

            out = response.getOutputStream();
            document.write(out);
            document.close();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 创建标题
     *
     * @param document 文档
     * @param message  标题内容
     * @param style    标题等级
     * @param line     缩进
     * @param fontSize 字体大小
     */
    public static void createTitle(XWPFDocument document, String message, String style, int line, int fontSize) {
        XWPFParagraph summaeTableParagraph = WordUtils.getLeftParagraph(document);
        summaeTableParagraph.setStyle(style);
        summaeTableParagraph.setIndentationFirstLine(line);
        XWPFRun summaeTableRun = summaeTableParagraph.createRun();
        WordUtils.addParagraph(summaeTableRun, "宋体", fontSize, "000000", message, false);
    }

    /**
     * 创建图片在word中
     *
     * @param document 文档
     * @param image    图片base64
     * @param name     图片名
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void createPic(XWPFDocument document, String image, String name) throws IOException, InvalidFormatException {
        XWPFParagraph picParagraph = WordUtils.getCenterParagraph(document);
        XWPFRun createRun = picParagraph.createRun();
        byte[] base64Info = decodeBase64(image);
        InputStream in = new ByteArrayInputStream(base64Info);
        createRun.addPicture(in, 5, name, Units.toEMU(410), Units.toEMU(170));
    }

    /**
     * 创建地图
     *
     * @param document 文档
     * @param image    图片base64
     * @param name     图片名
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void createMap(XWPFDocument document, String image, String name) throws IOException, InvalidFormatException {
        XWPFParagraph picParagraph = WordUtils.getCenterParagraph(document);
        XWPFRun createRun = picParagraph.createRun();
        byte[] base64Info = decodeBase64(image);
        InputStream in = new ByteArrayInputStream(base64Info);
        createRun.addPicture(in, 5, name, Units.toEMU(410), Units.toEMU(210));
    }

    /**
     * 创建表格
     *
     * @param document
     * @return
     */
    public static XWPFTable createTable(XWPFDocument document) {
        XWPFTable summaTable = document.createTable();
        // 列宽自动分割
        CTTblWidth summaTableWidth = summaTable.getCTTbl().addNewTblPr().addNewTblW();
        summaTableWidth.setType(STTblWidth.DXA);
        summaTableWidth.setW(BigInteger.valueOf(8160));
        return summaTable;
    }

    /**
     * 表格插入行数据
     *
     * @param document 文档
     * @param table    表格
     * @param head     是否是表头
     * @param values   数据内容
     */
    public static void insertRow(XWPFDocument document, XWPFTable table, XWPFParagraph excelParagraph, boolean head,
                                 String... values) {
        if (head) {
            XWPFTableRow summaTableRowOne = table.getRow(0);
            WordUtils.setExcelHeadContent(excelParagraph, summaTableRowOne, values);
        } else {
            XWPFTableRow summaTableRowOne = table.createRow();
            WordUtils.setExcelContent(excelParagraph, summaTableRowOne, values);
        }
    }

    /**
     * 解析base64，返回图片所在路径
     *
     * @param base64Info
     * @return
     */
    private byte[] decodeBase64(String base64Info) {
        if (StringUtils.isEmpty(base64Info)) {
            return null;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        if (!base64Info.contains("base64,"))
            return null;
        String[] arr = base64Info.split("base64,");
        // 数据中：data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABI4AAAEsCAYAAAClh/jbAAA
        // ... 在"base64,"之后的才是图片信息
        try {
            return decoder.decodeBuffer(arr[1]);
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 获取区域模板
     *
     * @return
     */
    @PostMapping("areaTemplate")
    @ResponseBody
    public HttpResult areaTemplate() {
        HttpResult result;
        List<RptPloy> datas;
        datas = reportService.getTemplate(Integer.valueOf(1));
        if (CollectionUtils.isEmpty(datas)) {
            result = PubUtils.assignmentResult(null, 500, "沒有对应的模板");
        } else {
            result = PubUtils.assignmentResult(datas, 200, "获取模板成功");
        }
        return result;
    }


    @PostMapping("area")
    @ResponseBody
    public HttpResult area(HttpServletRequest request, String startTime, String endTime, String area, String areaname, String jcwfb, String zjsjbg,
                           String zjsjtx, String zjmdbg, String zjmdtx, String zjsjditic, String zjsjdf47, String glfbzjfz, String glfbcxsj,
                           String sjglbg, String zjyybg, String zjyytx, String zjlxbg, String zjlxtx, String zjrlt) throws Exception {
        HttpResult result;
        List<Object> reList = new ArrayList<>();
        ReportAreaPojo reportAreaPojo = getAreaChoose(request, startTime, endTime, area, areaname, jcwfb, zjsjbg, zjsjtx, zjmdbg, zjmdtx,
                zjsjditic, zjsjdf47, glfbzjfz, glfbcxsj, sjglbg, zjyybg, zjyytx, zjlxbg, zjlxtx, zjrlt);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(reportAreaPojo.getStartTime(), reportAreaPojo.getEndTime(), "monitor");
        String userIndex = TokenManager.getUserId();
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return result;
        }
        try {
            DevMapInfo devMapInfo = new DevMapInfo();
            devMapInfo = areaService.getDevMap(reportAreaPojo.getArea());
            JSONArray devMapArray = JSONArray.fromObject(devMapInfo.getOnline());
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount",
                    stringInstantiateUtil.stringInstantiate(String.valueOf(devMapInfo.getMaps().size())), RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "devMapInfo", jsonArrayInstantiateUtil.stringInstantiate(devMapArray),
                    RedisDB.SHORT_TIME);
            AreaGeneral eventcount = areaService.getGeneralDate(reportAreaPojo.getArea(), datePojo.getStartTime(),
                    datePojo.getEndTime());
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventcount", stringInstantiateUtil.stringInstantiate(eventcount.getTotalTimes().toString()),
                    RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "isPro", stringInstantiateUtil.stringInstantiate(eventcount.getPro()), RedisDB.SHORT_TIME);
            /* 监测网分布 */
            List<LineMaps> maps = new ArrayList<>();
            if (reportAreaPojo.isJcwfb()) {
                maps = iOverviewServer.getLineMaps();
            }
            /* 暂降事件列表 */
            AreaGeneral analyzeInfos = new AreaGeneral();
            if (reportAreaPojo.isZjsjbg() || reportAreaPojo.isZjsjtx()) {
                analyzeInfos = areaService.getGeneralDate(reportAreaPojo.getArea(), datePojo.getStartTime(),
                        datePojo.getEndTime());

                if (analyzeInfos == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }

                List<Area> areas = new ArrayList<>();
                if (analyzeInfos.getPro() == "city") {
                    for (int i = 0; i < analyzeInfos.getArea().size(); i++) {
                        if (analyzeInfos.getArea().get(i).getCity().equals(analyzeInfos.getCityName())) {
                            areas.add(analyzeInfos.getArea().get(i));
                        }
                    }
                    analyzeInfos.setArea(areas);
                } else {
                    areas = analyzeInfos.getArea();
                }
                List<Voltage> vol = analyzeInfos.getVol();
                List<Interval> interval = analyzeInfos.getInterval();
                JSONArray areaArray = JSONArray.fromObject(areas);
                JSONArray volArray = JSONArray.fromObject(vol);
                JSONArray intervalArray = JSONArray.fromObject(interval);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "area", jsonArrayInstantiateUtil.stringInstantiate(areaArray), RedisDB.SHORT_TIME);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "vol", jsonArrayInstantiateUtil.stringInstantiate(volArray), RedisDB.SHORT_TIME);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "interval", jsonArrayInstantiateUtil.stringInstantiate(intervalArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降密度数据获取 */
            List<EventDensity> eventDensities = new ArrayList<>();
            if (reportAreaPojo.isZjmdtx()) {
                eventDensities = areaService.getEventDensity(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                if (eventDensities == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
            }
            List<List> eventDisdip;
            List<List> ec411;
            Iec28 iec28;
            if (reportAreaPojo.isZjmdbg()) {
                eventDisdip = areaService.getEventDisdip(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                ec411 = areaService.getIEC411(datePojo.getStartTime(), datePojo.getEndTime(), reportAreaPojo.getArea());
                iec28 = areaService.getIEC28(datePojo.getStartTime(), datePojo.getEndTime(), reportAreaPojo.getArea());
                if (eventDisdip == null || ec411 == null || iec28 == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
                List<List> ec28 = iec28.getData();
                JSONArray evArray = JSONArray.fromObject(eventDisdip);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventDisdip", jsonArrayInstantiateUtil.stringInstantiate(evArray),
                        RedisDB.SHORT_TIME);
                JSONArray ec4Array = JSONArray.fromObject(ec411);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "ec411", jsonArrayInstantiateUtil.stringInstantiate(ec4Array), RedisDB.SHORT_TIME);
                JSONArray ec2Array = JSONArray.fromObject(ec28);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "ec28", jsonArrayInstantiateUtil.stringInstantiate(ec2Array), RedisDB.SHORT_TIME);

                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "pertime", stringInstantiateUtil.stringInstantiate(iec28.getPertime()),
                        RedisDB.SHORT_TIME);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventvalue", stringInstantiateUtil.stringInstantiate(iec28.getEventvalue()),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降事件点图 */
            List<EventDataList> eventDataLists = new ArrayList<>();
            if (reportAreaPojo.isZjsjditic() || reportAreaPojo.isZjsjdf47()) {
                eventDataLists = areaService.getEventDataList(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                if (eventDataLists == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
            }
            /* 概率分布 */
            EventChance eventChance = new EventChance();
            if (reportAreaPojo.isGlfbzjfz() || reportAreaPojo.isGlfbcxsj()) {
                eventChance = areaService.getEventChance(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                if (eventChance == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
            }
            /* 事件关联 */
            List<EventAssObj> list = new ArrayList<>();
            if (reportAreaPojo.isSjglbg()) {

                list = rangeService.queryEventsByTime(reportAreaPojo.getStartTime(), reportAreaPojo.getEndTime());
                if (list == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
                JSONArray inArray = JSONArray.fromObject(list);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventass", jsonArrayInstantiateUtil.stringInstantiate(inArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降原因 */
            List<EventCause> eventCauses = new ArrayList<>();
            if (reportAreaPojo.isZjyybg() || reportAreaPojo.isZjyytx()) {
                eventCauses = areaService.getEventCause(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                if (eventCauses == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
                JSONArray caArray = JSONArray.fromObject(eventCauses);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventCauses", jsonArrayInstantiateUtil.stringInstantiate(caArray),
                        RedisDB.SHORT_TIME);
            }
            /* 暂降类型 */
            List<EventTypeList> eventTypeLists = new ArrayList<>();
            if (reportAreaPojo.isZjlxbg() || reportAreaPojo.isZjlxtx()) {
                eventTypeLists = areaService.getEventType(datePojo.getStartTime(), datePojo.getEndTime(),
                        reportAreaPojo.getArea());
                if (eventTypeLists == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
                JSONArray tyArray = JSONArray.fromObject(eventTypeLists);
                jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventTypeLists", jsonArrayInstantiateUtil.stringInstantiate(tyArray),
                        RedisDB.SHORT_TIME);
            }
            JSONObject reportPojo = JSONObject.fromObject(reportAreaPojo);
            String key = TokenManager.getUserId() + "reportPojo";
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, key, instantiateUtil.stringInstantiate(reportPojo), RedisDB.SHORT_TIME);
            /* 暂降热力图 */
            List<LineInfo> eventMap = new ArrayList<>();
            if (reportAreaPojo.isZjrlt()) {
                eventMap = areaService.getEventMaps(datePojo.getStartTime(), datePojo.getEndTime());
                if (eventMap == null) {
                    result = PubUtils.assignmentResult(null, 500, "该区域暂无数据");
                    return result;
                }
            }
            /* 将前台需要画图的数据返回 */
            reList.add(analyzeInfos);
            reList.add(eventDensities);
            reList.add(eventDataLists);
            reList.add(eventChance);
            reList.add(eventCauses);
            reList.add(eventTypeLists);
            reList.add(maps);
            reList.add(eventMap);
            result = PubUtils.assignmentResult(reList, 200, "获取监测点图表数据成功");
            userLog.getLog("查询区域报告", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } catch (Exception e) {
            // TODO: handle exception
            result = PubUtils.assignmentResult(null, 500, "获取监测点图表数据失败");
            userLog.getLog("查询区域报告", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        }
        return result;
    }

    /**
     * 根据用户页面的选择，指定我们需要查询的数据
     *
     * @param request 请求
     */
    private ReportAreaPojo getAreaChoose(HttpServletRequest request, String startTime, String endTime, String area, String areaname, String jcwfb, String zjsjbg,
                                         String zjsjtx, String zjmdbg, String zjmdtx, String zjsjditic, String zjsjdf47, String glfbzjfz, String glfbcxsj,
                                         String sjglbg, String zjyybg, String zjyytx, String zjlxbg, String zjlxtx, String zjrlt) {
        ReportAreaPojo reportAreaPojo = new ReportAreaPojo();
        reportAreaPojo.setJcwfb(Boolean.valueOf(jcwfb));
        reportAreaPojo.setZjsjbg(Boolean.valueOf(zjsjbg));
        reportAreaPojo.setZjsjtx(Boolean.valueOf(zjsjtx));
        reportAreaPojo.setZjmdbg(Boolean.valueOf(zjmdbg));
        reportAreaPojo.setZjmdtx(Boolean.valueOf(zjmdtx));
        reportAreaPojo.setZjsjditic(Boolean.valueOf(zjsjditic));
        reportAreaPojo.setZjsjdf47(Boolean.valueOf(zjsjdf47));
        reportAreaPojo.setGlfbzjfz(Boolean.valueOf(glfbzjfz));
        reportAreaPojo.setGlfbcxsj(Boolean.valueOf(glfbcxsj));
        reportAreaPojo.setSjglbg(Boolean.valueOf(sjglbg));
        reportAreaPojo.setZjyybg(Boolean.valueOf(zjyybg));
        reportAreaPojo.setZjyytx(Boolean.valueOf(zjyytx));
        reportAreaPojo.setZjlxbg(Boolean.valueOf(zjlxbg));
        reportAreaPojo.setZjlxtx(Boolean.valueOf(zjlxtx));
        reportAreaPojo.setZjrlt(Boolean.valueOf(zjrlt));
        reportAreaPojo.setStartTime(startTime);
        reportAreaPojo.setEndTime(endTime);
        reportAreaPojo.setArea(area);
        reportAreaPojo.setAreaname(areaname);
        return reportAreaPojo;

    }


    @PostMapping("exportAreaReport")
    @ResponseBody
    public String exportAreaReport(HttpServletRequest request, String devmapImage, String intervalImage, String districtImage, String voltageImage,
                                   String densityImage, String iticImage, String f47Image, String eventValueImage, String persisttimeImage,
                                   String timeImage, String causeImage, String typeImage, String eventmapImage, String itictips, String f47tips,
                                   String startTime, String endTime) throws Exception {
        String userIndex = TokenManager.getUserId();
        JSONObject jsonObject = instantiateUtil.deInstantiate(instantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex,
                TokenManager.getUserId() + "reportPojo")));
        ReportAreaPojo reportAreaPojo = (ReportAreaPojo) JSONObject.toBean(jsonObject, ReportAreaPojo.class);
        // 需要展示的图
        if (reportAreaPojo.isJcwfb()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "devmapImage", stringInstantiateUtil.stringInstantiate(devmapImage), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjsjtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "intervalImage", stringInstantiateUtil.stringInstantiate(intervalImage), RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "districtImage", stringInstantiateUtil.stringInstantiate(districtImage), RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "voltageImage", stringInstantiateUtil.stringInstantiate(voltageImage), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjmdtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "densityImage", stringInstantiateUtil.stringInstantiate(densityImage), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjsjditic()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "iticImage", stringInstantiateUtil.stringInstantiate(iticImage), RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "itictips", stringInstantiateUtil.stringInstantiate(itictips), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjsjdf47()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "f47Image", stringInstantiateUtil.stringInstantiate(f47Image), RedisDB.SHORT_TIME);
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "f47tips", stringInstantiateUtil.stringInstantiate(f47tips), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isGlfbzjfz()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventValueImage", stringInstantiateUtil.stringInstantiate(eventValueImage),
                    RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isGlfbcxsj()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "persisttimeImage", stringInstantiateUtil.stringInstantiate(persisttimeImage),
                    RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjyytx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "causeImage", stringInstantiateUtil.stringInstantiate(causeImage), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjlxtx()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "typeImage", stringInstantiateUtil.stringInstantiate(typeImage), RedisDB.SHORT_TIME);
        }
        if (reportAreaPojo.isZjrlt()) {
            jedisManager.hset(RedisDB.SHORT_TIME_QUERY, userIndex, "eventmapImage", stringInstantiateUtil.stringInstantiate(eventmapImage), RedisDB.SHORT_TIME);
        }
        return "success";
    }

    @GetMapping("downAreaReport")
    public void downAreaReport(HttpServletResponse response, HttpServletRequest request, String name) throws Exception {
        String userIndex = TokenManager.getUserId();
        JSONObject jsonObject = instantiateUtil.deInstantiate(instantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex,
                TokenManager.getUserId() + "reportPojo")));
        jedisManager.hdel(RedisDB.SHORT_TIME_QUERY, userIndex, TokenManager.getUserId() + "reportPojo");
        ReportAreaPojo reportAreaPojo = (ReportAreaPojo) JSONObject.toBean(jsonObject, ReportAreaPojo.class);
        int one = 1;
        // 开始做文档
        XWPFDocument document = new XWPFDocument();
        // 设定标题格式
        WordUtils.setHeadingStyle(document);
        // 添加标题
        XWPFParagraph titleParagraph = WordUtils.getCenterParagraph(document);
        WordUtils.addLine(titleParagraph, 11);
        // 设置段落居中
        XWPFRun titleParagraphRun = titleParagraph.createRun();
        WordUtils.addParagraph(titleParagraphRun, "宋体", 15, "000000", reportAreaPojo.getAreaname() + "供电公司", true);
        WordUtils.addLine(titleParagraph, 3);
        XWPFRun titleParagraphBigRun = titleParagraph.createRun();
        WordUtils.addParagraph(titleParagraphBigRun, "宋体", 36, "000000", "电压暂降事件区域报告", true);
        WordUtils.addLine(titleParagraph, 19);
        XWPFRun titleParagraphDateRun = titleParagraph.createRun();
        WordUtils.addParagraph(titleParagraphDateRun, "宋体", 14, "000000", "日期：" + WordUtils.getRightNow(), true);
        titleParagraph.setPageBreak(true);
        // 段落
        XWPFParagraph statisticsParagraph = WordUtils.getCenterParagraph(document);
        // 段前分页
        statisticsParagraph.setPageBreak(true);
        XWPFRun statisticsRun = statisticsParagraph.createRun();
        WordUtils.addParagraph(statisticsRun, "宋体", 24, "000000", "电压暂降事件区域报告", false);
        createTitle(document, "1. 引言", "标题 1", 0, 15);
        XWPFParagraph introductionContentParagraph = WordUtils.getLeftParagraph(document);
        // 首行缩进---段落
        introductionContentParagraph.setIndentationFirstLine(200);
        XWPFRun introductionContentRun = introductionContentParagraph.createRun();

        List<DeviceValue> devmap;
        JSONArray dev = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "devMapInfo")));
        devmap = (List<DeviceValue>) JSONArray.toCollection(dev, DeviceValue.class);

        String pro = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "isPro")));
        String yy;
        if (pro == "pro") {
            yy = reportAreaPojo.getAreaname() + "电网总共有"
                    + stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount") + "个监测点，"
                    + String.valueOf(devmap.size()))) + "个市(州)电压暂降监测点分布情况如下所示：";
            for (int i = 0; i < devmap.size(); i++) {
                if (i != devmap.size() - 1) {
                    yy = yy + devmap.get(i).getName() + "：" + devmap.get(i).getAmounts() + "个，";
                } else {
                    yy = yy + devmap.get(i).getName() + "：" + devmap.get(i).getAmounts() + "个。";
                }
            }
        } else {
            yy = reportAreaPojo.getAreaname() + "电网总共有"
                    + stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount"))) + "个监测点。";
        }
        WordUtils.addParagraph(introductionContentRun, "宋体", 11, "000000", yy, false);

        String eventcount = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventcount")));
        WordUtils.addParagraph(introductionContentRun, "宋体", 11, "000000",
                reportAreaPojo.getAreaname() + "电网在所选择时间段" + reportAreaPojo.getStartTime() + " 至 "
                        + reportAreaPojo.getEndTime() + "累计监测到暂降事件" + eventcount
                        + "条，本报告按照监测点分布，暂降事件统计，暂降事件点图，暂降热力图，暂降密度图，暂降概率分布图，事件关联统计，暂降类型统计，暂降原因统计等方面进行数据分析。",
                false);
        createTitle(document, "2. 报告分析对象", "标题 1", 0, 15);
        XWPFParagraph objectContentParagraph = WordUtils.getLeftParagraph(document);
        objectContentParagraph.setIndentationFirstLine(200);
        XWPFRun objectContentRun = objectContentParagraph.createRun();
        WordUtils.addParagraph(objectContentRun, "宋体", 11, "000000", reportAreaPojo.getAreaname() + "。", false);
        createTitle(document, "3. 报告分析时间", "标题 1", 0, 15);
        XWPFParagraph timeContentParagraph = WordUtils.getLeftParagraph(document);
        timeContentParagraph.setIndentationFirstLine(200);
        XWPFRun timeContentRun = timeContentParagraph.createRun();
        WordUtils.addParagraph(timeContentRun, "宋体", 11, "000000",
                reportAreaPojo.getStartTime() + " 至 " + reportAreaPojo.getEndTime() + "。", false);
        createTitle(document, "4. 汇总信息", "标题 1", 0, 15);

        String tips;
        /* 监测网分布 */
        if (reportAreaPojo.isJcwfb()) {
            createTitle(document, "4." + one + " 监测网分布", "标题 2", 200, 11);
            XWPFParagraph jcwfbtParagraph = WordUtils.getLeftParagraph(document);
            jcwfbtParagraph.setIndentationFirstLine(200);
            XWPFRun jcwfbContentRun = jcwfbtParagraph.createRun();
            Integer oncount = 0;
            Integer offcount = 0;
            Integer totalcount = Integer.valueOf(stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount"))));
            for (int i = 0; i < devmap.size(); i++) {
                oncount = oncount + devmap.get(i).getOncount();
                offcount = offcount + devmap.get(i).getOffcount();
            }
            float rate = (Float.valueOf(oncount) / Float.valueOf(totalcount)) * 100;
            DecimalFormat df = new DecimalFormat("0.00");
            tips = new String();
            if (pro == "pro") {
                tips = reportAreaPojo.getAreaname() + "电网总共有监测点"
                        + stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount"))) + "个，其中";
                tips = tips + devmap.get(0).getName() + "、" + devmap.get(1).getName() + "监测点数量较多 ，监测点在线率达到"
                        + df.format(rate) + "%（通讯正常为：" + String.valueOf(oncount) + "个，通讯异常为：" + String.valueOf(offcount)
                        + "个）[在线率=通讯正常点数/总监测点数（统计时候排除检修和检修监测点）]，具体见下图";
            } else {
                tips = reportAreaPojo.getAreaname() + "电网总共有监测点"
                        + stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "linecount"))) + "个。";
                tips = tips + "监测点在线率达到" + df.format(rate) + "%（通讯正常为：" + String.valueOf(oncount) + "个，通讯异常为："
                        + String.valueOf(offcount) + "个）[通讯正常/总监测点数（统计时候排除检修和检修监测点）]，具体见下图：";
            }
            WordUtils.addParagraph(jcwfbContentRun, "宋体", 11, "000000", tips, false);
            String devmapImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "devmapImage")));
            createMap(document, devmapImage, "监测网分布");
            one++;
        }
        /* 暂降事件列表 */
        if (reportAreaPojo.isZjsjbg() || reportAreaPojo.isZjsjtx()) {
            createTitle(document, "4." + one + " 暂降事件列表", "标题 2", 200, 11);
            XWPFParagraph zjsjlbParagraph = WordUtils.getLeftParagraph(document);
            zjsjlbParagraph.setIndentationFirstLine(200);
            XWPFRun zjsjlbContentRun = zjsjlbParagraph.createRun();

            List<Area> area;
            List<Voltage> vol;
            List<Interval> interval;
            JSONArray ar = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "area")));
            area = (List<Area>) JSONArray.toCollection(ar, Area.class);

            JSONArray vo = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "vol")));
            vol = (List<Voltage>) JSONArray.toCollection(vo, Voltage.class);

            JSONArray in = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "interval")));
            interval = (List<Interval>) JSONArray.toCollection(in, Interval.class);

            List<Voltage> voldesc = (List<Voltage>) JSONArray.toCollection(vo, Voltage.class);
            List<Interval> intervaldesc = (List<Interval>) JSONArray.toCollection(in, Interval.class);
            Collections.sort(voldesc, new Comparator<Voltage>() {
                /*
                 * 返回一个基本类型的整型， 返回负数表示：p1 小于p2， 返回0 表示：p1和p2相等， 返回正数表示：p1大于p2
                 */
                public int compare(Voltage p1, Voltage p2) {
                    if (p2.getTimes() > p1.getTimes()) {
                        return 1;
                    }
                    if (p2.getTimes() == p1.getTimes()) {
                        return 0;
                    }
                    return -1;
                }
            });
            Collections.sort(intervaldesc, new Comparator<Interval>() {
                /*
                 * 返回一个基本类型的整型， 返回负数表示：p1 小于p2， 返回0 表示：p1和p2相等， 返回正数表示：p1大于p2
                 */
                public int compare(Interval p1, Interval p2) {
                    if (p2.getTimes() > p1.getTimes()) {
                        return 1;
                    }
                    if (p2.getTimes() == p1.getTimes()) {
                        return 0;
                    }
                    return -1;
                }
            });
            tips = new String();
            tips = reportAreaPojo.getAreaname() + "电网在所选择的分析时间段内累计监测暂降记录" + eventcount + "条";
            if (pro == "pro") {
                if (area.size() > 0) {
                    tips = tips + "，其中" + area.get(0).getCity();
                    if (area.size() > 1) {
                        tips = tips + "、" + area.get(1).getCity();
                    }
                    tips = tips + "暂降事件居多";
                }
            }
            if (voldesc.size() > 0) {
                tips = tips + "，" + voldesc.get(0).getVoltageValue();
                if (vol.size() > 1) {
                    tips = tips + "、" + voldesc.get(1).getVoltageValue();
                }
                tips = tips + "暂降事件居多";
            }
            if (interval.size() > 0) {
                tips = tips + "，" + intervaldesc.get(0).getMonth();
                if (interval.size() > 1) {
                    tips = tips + "、" + intervaldesc.get(1).getMonth();
                }
                tips = tips + "月暂降事件居多";
            }
            tips = tips + "，具体见下表(图)：";
            WordUtils.addParagraph(zjsjlbContentRun, "宋体", 11, "000000", tips, false);

            int two = 1;
            if (reportAreaPojo.isZjsjtx()) {
                createTitle(document, "4." + one + "." + two + " 暂降事件图形", "标题 3", 400, 11);
                String districtImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "districtImage")));
                createPic(document, districtImage, "按区域统计");

                String intervalImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "intervalImage")));
                createPic(document, intervalImage, "按月份统计");

                String voltageImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "voltageImage")));
                createPic(document, voltageImage, "按区域统计");
                two++;
            }
            if (reportAreaPojo.isZjsjbg()) {
                createTitle(document, "4." + one + "." + two + " 暂降事件表格", "标题 3", 400, 11);

                XWPFTable sum = createTable(document);
                XWPFParagraph sumExcelParagraph = WordUtils.getCenterParagraph(document);
                insertRow(document, sum, sumExcelParagraph, true, "区域 ", "电压暂降次数");
                if (area.isEmpty()) {
                    insertRow(document, sum, sumExcelParagraph, false, "", "");
                } else {
                    for (int i = 0; i < area.size(); i++) {
                        insertRow(document, sum, sumExcelParagraph, false, area.get(i).getCity(),
                                String.valueOf(area.get(i).getTimes()));
                    }
                }

                XWPFTable volsum = createTable(document);
                XWPFParagraph volsumExcelParagraph = WordUtils.getCenterParagraph(document);
                insertRow(document, volsum, volsumExcelParagraph, true, "电压等级 ", "电压暂降次数");
                if (vol.isEmpty()) {
                    insertRow(document, volsum, volsumExcelParagraph, false, "", "");
                } else {
                    for (int i = 0; i < vol.size(); i++) {
                        insertRow(document, volsum, volsumExcelParagraph, false, vol.get(i).getVoltageValue(),
                                String.valueOf(vol.get(i).getTimes()));
                    }
                }

                XWPFTable intsum = createTable(document);
                XWPFParagraph intsumExcelParagraph = WordUtils.getCenterParagraph(document);
                insertRow(document, intsum, intsumExcelParagraph, true, "月份 ", "电压暂降次数");
                if (interval.isEmpty()) {
                    insertRow(document, intsum, intsumExcelParagraph, false, "", "");
                } else {
                    for (int i = 0; i < interval.size(); i++) {
                        insertRow(document, intsum, intsumExcelParagraph, false, interval.get(i).getMonth(),
                                String.valueOf(interval.get(i).getTimes()));
                    }
                }
            }
            one++;
        }
        /* 暂降事件点图 */
        if (reportAreaPojo.isZjsjditic() || reportAreaPojo.isZjsjdf47()) {
            createTitle(document, "4." + one + " 暂降事件点图", "标题 2", 200, 11);

            XWPFParagraph zjsjdParagraph = WordUtils.getLeftParagraph(document);
            zjsjdParagraph.setIndentationFirstLine(200);
            XWPFRun zjsjdContentRun = zjsjdParagraph.createRun();

            tips = new String();
            tips = "暂降事件点图统计分成ITIC曲线和F47曲线展示。";
            WordUtils.addParagraph(zjsjdContentRun, "宋体", 11, "000000", tips, false);
            int two = 1;
            if (reportAreaPojo.isZjsjditic()) {
                createTitle(document, "4." + one + "." + two + " ITIC曲线", "标题 3", 400, 11);

                XWPFParagraph iticParagraph = WordUtils.getLeftParagraph(document);
                iticParagraph.setIndentationFirstLine(200);
                XWPFRun iticContentRun = iticParagraph.createRun();

                tips = new String();
                tips = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "itictips")));
                WordUtils.addParagraph(iticContentRun, "宋体", 11, "000000", tips, false);
                String iticImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "iticImage")));
                createPic(document, iticImage, "ITIC曲线");
                two++;
            }
            if (reportAreaPojo.isZjsjdf47()) {
                createTitle(document, "4." + one + "." + two + " F47曲线", "标题 3", 400, 11);

                XWPFParagraph f47Paragraph = WordUtils.getLeftParagraph(document);
                f47Paragraph.setIndentationFirstLine(200);
                XWPFRun f47ContentRun = f47Paragraph.createRun();

                tips = new String();
                tips = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "f47tips")));
                WordUtils.addParagraph(f47ContentRun, "宋体", 11, "000000", tips, false);
                String f47Image = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "f47Image")));
                createPic(document, f47Image, "F47曲线");
            }
            one++;
        }
        /* 暂降密度 */
        if (reportAreaPojo.isZjmdtx() || reportAreaPojo.isZjmdbg()) {
            createTitle(document, "4." + one + " 暂降密度", "标题 2", 200, 11);

            XWPFParagraph zjmdParagraph = WordUtils.getLeftParagraph(document);
            zjmdParagraph.setIndentationFirstLine(200);
            XWPFRun zjmdContentRun = zjmdParagraph.createRun();
            String pertime = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "pertime")));
            String eventvalue = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventvalue")));
            tips = new String();
            tips = "暂降密度统计可以从幅值和持续时间两个维度直接地反映暂降事件发生情况，主要反应事件的发生次数，";
            tips = tips + reportAreaPojo.getAreaname() + "电网在所选择的分析时间内暂降事件主要集中在幅值为" + eventvalue + "，持续时间为" + pertime
                    + "[根据 IEC 61000-2-8:(公共电网电压暂降测量统计)算出暂降事件发生最多的区间],具体见表（图）：";
            WordUtils.addParagraph(zjmdContentRun, "宋体", 11, "000000", tips, false);
            int two = 1;
            if (reportAreaPojo.isZjmdtx()) {
                createTitle(document, "4." + one + "." + two + " 暂降密度图", "标题 3", 400, 11);
                String densityImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "densityImage")));
                createPic(document, densityImage, "暂降密度图");
                two++;
            }
            if (reportAreaPojo.isZjmdbg()) {
                createTitle(document, "4." + one + "." + two + " DISDIP表格:国际发配电联盟(UNIPEDE)", "标题 3", 400, 11);
                XWPFTable disdip = createTable(document);
                XWPFParagraph disdipExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> eventDisdip;
                JSONArray arrayeventDisdip = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventDisdip")));
                eventDisdip = (List<List>) JSONArray.toCollection(arrayeventDisdip, ArrayList.class);
                insertRow(document, disdip, disdipExcelParagraph, true, "剩余电压", "20ms", "100ms", "500ms", "1s", "3s",
                        "20s", "60s", "180s");
                if (eventDisdip.isEmpty()) {
                    insertRow(document, disdip, disdipExcelParagraph, false, "", "", "", "", "", "", "", "", "");
                } else {
                    for (List list : eventDisdip) {
                        insertRow(document, disdip, disdipExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString(),
                                list.get(7).toString(), list.get(8).toString());
                    }
                }
                two++;
                createTitle(document, "4." + one + "." + two + " IEC 61000-4-11:(用电终端的电压暂降抗度)", "标题 3", 400, 11);
                XWPFTable ec411Table = createTable(document);
                XWPFParagraph ec411TableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> ec411;
                JSONArray arrayec411 = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "ec411")));
                ec411 = (List<List>) JSONArray.toCollection(arrayec411, ArrayList.class);
                insertRow(document, ec411Table, ec411TableExcelParagraph, true, "剩余电压", "10~20ms", "20~100ms",
                        "0.1~0.2s", "0.2~0.5s", "0.5~1s", ">1s");
                if (ec411.isEmpty()) {
                    insertRow(document, ec411Table, ec411TableExcelParagraph, false, "", "", "", "", "", "", "");
                } else {
                    for (List list : ec411) {
                        insertRow(document, ec411Table, ec411TableExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString());
                    }
                }
                two++;
                createTitle(document, "4." + one + "." + two + " IEC 61000-2-8:(公共电网电压暂降测量统计)", "标题 3", 400, 11);
                XWPFTable ec28Table = createTable(document);
                XWPFParagraph ec28TableExcelParagraph = WordUtils.getCenterParagraph(document);
                List<List> ec28;
                JSONArray arrayec28 = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "ec28")));
                ec28 = (List<List>) JSONArray.toCollection(arrayec28, ArrayList.class);
                insertRow(document, ec28Table, ec28TableExcelParagraph, true, "剩余电压", "0.02~0.1s", "0.1~0.25s",
                        "0.25~0.5s", "0.5~1s", "1~3s", "3~20s", "20~60s", "60~180s");
                if (ec28.isEmpty()) {
                    insertRow(document, ec28Table, ec28TableExcelParagraph, false, "", "", "", "", "", "", "", "", "");
                } else {
                    for (List list : ec28) {
                        insertRow(document, ec28Table, ec28TableExcelParagraph, false, list.get(0).toString(),
                                list.get(1).toString(), list.get(2).toString(), list.get(3).toString(),
                                list.get(4).toString(), list.get(5).toString(), list.get(6).toString(),
                                list.get(7).toString(), list.get(8).toString());
                    }
                }
            }
            one++;
        }
        /* 概率分布 */
        if (reportAreaPojo.isGlfbcxsj() || reportAreaPojo.isGlfbzjfz()) {
            createTitle(document, "4." + one + " 暂降幅值概率分布图", "标题 2", 200, 11);

            XWPFParagraph glfbParagraph = WordUtils.getLeftParagraph(document);
            glfbParagraph.setIndentationFirstLine(200);
            XWPFRun glfbContentRun = glfbParagraph.createRun();
            String pertime = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "pertime")));
            String eventvalue = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventvalue")));
            tips = new String();
            tips = "暂降概率分布图分成暂降幅值概率分布和持续时间概率分布图，";
            tips = tips + reportAreaPojo.getAreaname() + "电网在所选择的分析时间内暂降事件从幅值概率分布统计主要集中在幅值为" + eventvalue
                    + "之间，从持续时间统计主要集中在持续时间为" + pertime + "[持续时间排序，选择暂降记录发生最多的区域]，如下表（图）：";
            WordUtils.addParagraph(glfbContentRun, "宋体", 11, "000000", tips, false);
            int two = 1;
            if (reportAreaPojo.isGlfbzjfz()) {
                createTitle(document, "4." + one + "." + two + " 暂降幅值的概率分函数", "标题 3", 400, 11);
                String eventValueImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventValueImage")));
                createPic(document, eventValueImage, "暂降幅值的概率分布函数");
                two++;
            }
            if (reportAreaPojo.isGlfbcxsj()) {
                createTitle(document, "4." + one + "." + two + " 持续时间的概率分函数", "标题 3", 400, 11);
                String persisttimeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "persisttimeImage")));
                createPic(document, persisttimeImage, "持续时间的概率分函数");
            }
            one++;
        }
        /* 事件关联分析 */
        if (reportAreaPojo.isSjglbg()) {
            createTitle(document, "4." + one + " 事件关联分析", "标题 2", 200, 11);
            List<EventAssObj> eventass;
            JSONArray arrayeventass = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventass")));
            eventass = (List<EventAssObj>) JSONArray.toCollection(arrayeventass, EventAssObj.class);

            XWPFParagraph sjglParagraph = WordUtils.getLeftParagraph(document);
            sjglParagraph.setIndentationFirstLine(200);
            XWPFRun sjglContentRun = sjglParagraph.createRun();
            tips = new String();
            tips = reportAreaPojo.getAreaname() + "电网在所选择的分析时间段内累计监测暂降记录" + eventcount + "条，归一化统计后共"
                    + String.valueOf(eventass.size()) + "[此为归一化后的暂态事件结果]条，,具体如下图所示：";
            WordUtils.addParagraph(sjglContentRun, "宋体", 11, "000000", tips, false);
            XWPFTable intervalsTable = createTable(document);
            XWPFParagraph intervalsTableExcelParagraph = WordUtils.getCenterParagraph(document);
            insertRow(document, intervalsTable, intervalsTableExcelParagraph, true, "时间", "事件关联分析名称", "事件关联分析描述");
            if (eventass.isEmpty()) {
                insertRow(document, intervalsTable, intervalsTableExcelParagraph, false, "", "");
            } else {
                for (EventAssObj eventas : eventass) {
                    insertRow(document, intervalsTable, intervalsTableExcelParagraph, false,
                            PubUtils.date2String(eventas.getTime(), "yyyy-MM-dd HH:mm:ss"), eventas.getName(),
                            eventas.getDescribe());
                }
            }
            one++;
        }
        /* 原因统计 */
        if (reportAreaPojo.isZjyytx() || reportAreaPojo.isZjyybg()) {
            createTitle(document, "4." + one + " 原因统计", "标题 2", 200, 11);
            List<EventCause> eventCauses;
            JSONArray arrayeventCauses = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventCauses")));
            eventCauses = (List<EventCause>) JSONArray.toCollection(arrayeventCauses, EventCause.class);

            Collections.sort(eventCauses, new Comparator<EventCause>() {
                /*
                 * int compare(Person p1, Person p2) 返回一个基本类型的整型， 返回负数表示：p1
                 * 小于p2， 返回0 表示：p1和p2相等， 返回正数表示：p1大于p2
                 */
                public int compare(EventCause p1, EventCause p2) {
                    // 按照Person的年龄进行升序排列
                    if (p2.getCount() > p1.getCount()) {
                        return 1;
                    }
                    if (p2.getCount() == p1.getCount()) {
                        return 0;
                    }
                    return -1;
                }
            });

            XWPFParagraph reasonParagraph = WordUtils.getLeftParagraph(document);
            reasonParagraph.setIndentationFirstLine(200);
            XWPFRun reasonContentRun = reasonParagraph.createRun();
            tips = new String();
            tips = reportAreaPojo.getAreaname() + "电网在所选择的分析时间内暂态事件主要的暂态原因为" + eventCauses.get(0).getCause()
                    + "[根据表格中的次数来进行分析]，见下表（图）：";
            WordUtils.addParagraph(reasonContentRun, "宋体", 11, "000000", tips, false);
            int two = 1;
            if (reportAreaPojo.isZjyytx()) {
                createTitle(document, "4." + one + "." + two + " 原因统计图", "标题 3", 400, 11);
                String causeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "causeImage")));
                createPic(document, causeImage, "原因统计图");
                two++;
            }
            if (reportAreaPojo.isZjyybg()) {
                createTitle(document, "4." + one + "." + two + " 原因统计表格", "标题 3", 400, 11);
                XWPFTable causeTable = createTable(document);
                XWPFParagraph causeTableExcelParagraph = WordUtils.getCenterParagraph(document);
                insertRow(document, causeTable, causeTableExcelParagraph, true, "暂态原因", "电压暂降次数");
                if (eventCauses.isEmpty()) {
                    insertRow(document, causeTable, causeTableExcelParagraph, false, "", "");
                } else {
                    for (EventCause eventCause : eventCauses) {
                        insertRow(document, causeTable, causeTableExcelParagraph, false, eventCause.getCause(),
                                String.valueOf(eventCause.getCount()));
                    }
                }
            }
            one++;
        }
        /* 类型统计 */
        if (reportAreaPojo.isZjlxtx() || reportAreaPojo.isZjlxbg()) {
            createTitle(document, "4." + one + " 类型统计", "标题 2", 200, 11);
            List<EventTypeList> eventTypeLists = new ArrayList();
            JSONArray arrayeventTypes = jsonArrayInstantiateUtil.deInstantiate(jsonArrayInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventTypeLists")));
            eventTypeLists = (List<EventTypeList>) JSONArray.toCollection(arrayeventTypes, EventTypeList.class);

            Collections.sort(eventTypeLists, new Comparator<EventTypeList>() {
                /*
                 * int compare(Person p1, Person p2) 返回一个基本类型的整型， 返回负数表示：p1
                 * 小于p2， 返回0 表示：p1和p2相等， 返回正数表示：p1大于p2
                 */
                @Override
                public int compare(EventTypeList p1, EventTypeList p2) {
                    // 按照Person的年龄进行升序排列
                    if (p2.getCount() > p1.getCount()) {
                        return 1;
                    }
                    if (p2.getCount() == p1.getCount()) {
                        return 0;
                    }
                    return -1;
                }
            });

            XWPFParagraph typeParagraph = WordUtils.getLeftParagraph(document);
            typeParagraph.setIndentationFirstLine(200);
            XWPFRun typeContentRun = typeParagraph.createRun();
            tips = new String();
            tips = reportAreaPojo.getAreaname() + "电网在所选择的分析时间内暂态事件主要的暂态类型为" + eventTypeLists.get(0).getType()
                    + "[根据表格中的次数来进行分析]，见下表（图）：";
            WordUtils.addParagraph(typeContentRun, "宋体", 11, "000000", tips, false);
            int two = 1;
            if (reportAreaPojo.isZjlxtx()) {
                createTitle(document, "4." + one + "." + two + " 类型统计图", "标题 3", 400, 11);
                String typeImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "typeImage")));
                createPic(document, typeImage, "类型统计图");
                two++;
            }
            if (reportAreaPojo.isZjlxbg()) {
                createTitle(document, "4." + one + "." + two + " 类型统计表格", "标题 3", 400, 11);
                XWPFTable typeTable = createTable(document);
                XWPFParagraph typeTableExcelParagraph = WordUtils.getCenterParagraph(document);
                insertRow(document, typeTable, typeTableExcelParagraph, true, "暂态类型", "电压暂态次数");
                if (eventTypeLists.isEmpty()) {
                    insertRow(document, typeTable, typeTableExcelParagraph, false, "", "");
                } else {
                    for (EventTypeList eventTypeList : eventTypeLists) {
                        insertRow(document, typeTable, typeTableExcelParagraph, false, eventTypeList.getType(),
                                String.valueOf(eventTypeList.getCount()));
                    }
                }
            }
            one++;
        }
        /* 暂降热力图 */
        if (reportAreaPojo.isZjrlt()) {
            createTitle(document, "4." + one + " 暂降热力图", "标题 2", 200, 11);

            XWPFParagraph zjrltParagraph = WordUtils.getLeftParagraph(document);
            zjrltParagraph.setIndentationFirstLine(200);
            XWPFRun zjrltContentRun = zjrltParagraph.createRun();
            tips = new String();
            tips = reportAreaPojo.getAreaname() + "网在所选择的分析时间段内累计监测暂降记录" + eventcount
                    + "条，使用颜色将地图上按照暂降记录发生频率进行描绘，所形成的热力具体见下图：";
            WordUtils.addParagraph(zjrltContentRun, "宋体", 11, "000000", tips, false);
            String eventmapImage = stringInstantiateUtil.deInstantiate(stringInstantiateUtil.stringDeInstantiate(jedisManager.hget(RedisDB.SHORT_TIME_QUERY, userIndex, "eventmapImage")));
            System.out.println(eventmapImage);
            createMap(document, eventmapImage, "暂降热力图");
            one++;
        }
        OutputStream out;
        try {
            response.setContentType("application/force-download");// 设置强制下载不打开
            // response.addHeader("Content-Disposition",
            // "attachment;fileName="+new
            // String(name.getBytes("GB2312"),"iso8859-1")+".docx" );// 设置文件名
            String agent = request.getHeader("User-Agent").toUpperCase(); // 获得浏览器信息并转换为大写
            if (agent.indexOf("MSIE") > 0 || (agent.indexOf("GECKO") > 0 && agent.indexOf("RV:11") > 0)) { // IE浏览器和Edge浏览器
                name = URLEncoder.encode(name, "UTF-8");
            } else { // 其他浏览器
//            	name = new String(name.getBytes("UTF-8"), "iso-8859-1");
                name = URLEncoder.encode(name, "UTF-8");
            }
            response.addHeader("Content-Disposition", "attachment;fileName=" + name + ".docx");// 设置文件名
            out = response.getOutputStream();
            document.write(out);
            document.close();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 电压暂降列表，获取列表数据
     *
     * @param startTime 起始时间
     * @param endTime   结束事件
     * @param area      区域名称
     */
    @RequestMapping(value = "getEventList", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getEventList(String startTime, String endTime, String area, String type, String waveType, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDateTime(startTime, endTime, "getEventList");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        // 统计时间段内的暂降原因次数、暂降类型次数
        List<EventDetail> voltageList;
        try {
            if (StringUtils.isEmpty(waveType) || waveType.equals("")) {
                voltageList = eventDetailService.getVolList(datePojo.getStartTime(), datePojo.getEndTime(), area, type, null, null, null, null, null, null, null, null, null, null);
            } else {
                voltageList = eventDetailService.getVolListByType(datePojo.getStartTime(), datePojo.getEndTime(), area, type, waveType, null, null, null, null, null, null, null, null, null, null);
            }
            if (null == voltageList) {
                result = PubUtils.assignmentResultLog(null, 500, "没有暂降列表的数据", "查询区域暂降列表", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(voltageList, 200, "获取暂降数据成功", "查询区域暂降列表", "成功", result);
            }
        } catch (Exception e) {
            logger.error("后台获取数据出错，方法名为：getEventList，异常为：" + e);
            result = PubUtils.assignmentResultLog(null, 500, "获取暂降数据失败", "查询区域暂降列表", "失败", result);
        }
        result.setResult(userUtil.getPro(area));
        return result;
    }

    /**
     * 生成暂降事件报告
     */
    @PostMapping("createEventReport")
    @ResponseBody
    public HttpResult createEventReport(@RequestParam("index[]") List<String> index, HttpSession session) {
        HttpResult result;
        if (CollectionUtils.isEmpty(index)) {
            result = PubUtils.assignmentResult(null, 500, "请选中需要下载的波形");
            return result;
        }

        try {
            WordUtil wordUtil = new WordUtil();
            for (int i = 0; i < index.size(); i++) {
                WaveData waveData = waveService.getWavedata(index.get(i), 1);
                //数据筛选,如果是双路电压的话，会存在2个波形数据
                List<WaveDataDetail> waveDataDetails = waveService.filteWaveData(waveData);
                if (waveData.getSunData().size() == 0) {
                    result = PubUtils.assignmentResult(null, 500, "没有波形数据");
                } else {
                    String time = waveData.getTime();
                    time = time.replace(" ", "%20");
                    String title = "监测点名称：" + waveData.getLineName() + "%20发生时刻：" + time + "%20特征幅值：" + waveData.getEventValue() + "%25%20持续时间：" + waveData.getPersistTime() + "s";

                    List<String> shun = new ArrayList<>();
                    List<String> rms = new ArrayList<>();
                    if (waveDataDetails.size() == 1) {
                        shun.add(waveService.createShunTitle(title, waveDataDetails.get(0)));
                        rms.add(waveService.createRMSTitle(title, waveDataDetails.get(0)));
                    } else {
                        shun.add(waveService.createShunTitle(title, waveDataDetails.get(0)));
                        rms.add(waveService.createRMSTitle(title, waveDataDetails.get(0)));
                        for (int n = 1; n < waveDataDetails.size(); n++) {
                            shun.add(waveService.createShun(waveDataDetails.get(n)));
                            rms.add(waveService.createRMS(waveDataDetails.get(n)));
                        }
                    }
                    wordUtil.translateShun(i, shun);
                    wordUtil.translateRms(i, rms);
                    List<EventEigDetail> eventDetailEigenvalue = eventDetailService.eventDetailEigenvalue(index.get(i));
                    wordUtil.setEventDetailEigenvalue(i, eventDetailEigenvalue);
                    EventInfoDetail eventInfoList = eventDetailService.eventDetailBaseInfoByIndex(index.get(i));
                    wordUtil.setEventInfoList(i, eventInfoList);
                }
            }
            wordUtil.createReport(index.size());
            result = PubUtils.assignmentResult(null, 200, "事件报告生成完毕");

            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");// 报告时分秒格式
            String fileName = "暂降事件报告_" + formatter.format(new Date()) + ".docx";
            //读取配置文件
            Properties pros = PubUtils.readProperties(getClass().getClassLoader(), "java.properties");
            String tmpPath = pros.get("TMP_PATH").toString() + File.separator + "eventreoprt";
            tmpPath = ClearPathUtil.cleanString(tmpPath);
            OutputStream os = null;
            File tmpfile = new File(tmpPath);
            if (!tmpfile.exists()) {
                tmpfile.mkdir();
            }
            tmpPath = tmpPath + File.separator + fileName;
            tmpPath = ClearPathUtil.cleanString(tmpPath);
            File tmp = new File(tmpPath);
            if (tmp.exists()) {
                tmp.delete();
            }
            PubUtils.createFile(tmpPath);
            try {
                os = new FileOutputStream(tmpPath);
                if (null != wordUtil.getDocument()) {
                    wordUtil.getDocument().write(os);
                    session.setAttribute("eventFilePath", tmpPath);
                    session.setAttribute("eventFileName", fileName);
                }
            } catch (Exception e) {
                session.setAttribute("eventFilePath", "");
                session.setAttribute("eventFileName", "");
                logger.error("输出暂态事件报告异常，原因为：" + e.toString());
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                } catch (Exception e) {
                    logger.error("关闭流异常，原因为：" + e.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("生成事件报告失败，方法名为：getEventReport，异常为：" + e.toString());
            result = PubUtils.assignmentResult(null, 500, "生成事件报告出错，请联系管理员");
        }

        return result;
    }

    @GetMapping("downEventReport")
    public void downEventReport(HttpServletResponse response, HttpSession session) throws UnsupportedEncodingException {
        String tmpPath = (String) session.getAttribute("eventFilePath");
        String filename = (String) session.getAttribute("eventFileName");

        // 设置输出的格式
        response.reset();
        response.setContentType("application/docx");
        response.addHeader("Content-Disposition",
                "attachment; filename=" + new String(filename.getBytes("gb2312"), "ISO8859-1"));
        // 循环取出流中的数据
        byte[] b = new byte[100];
        int len;
        if (StringUtils.isBlank(tmpPath)) {

        } else {
            if (!StringUtils.isBlank(tmpPath)) {
                tmpPath = ClearPathUtil.cleanString(tmpPath);
                // 读到流中
                InputStream inStream = null;
                try {
                    inStream = new FileInputStream(tmpPath);

                    if (null != inStream) {
                        while ((len = inStream.read(b)) > 0)
                            response.getOutputStream().write(b, 0, len);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    logger.error("读取报告信息失败：" + e.getMessage());
                } finally {
                    if (inStream != null) {
                        try {
                            inStream.close();
                        } catch (Exception e) {
                            logger.error("关闭输入流异常，异常为：" + e.toString());
                        }
                    }
                }

            }
            // 清除session中的数据
            session.removeAttribute("eventFilePath");
            session.removeAttribute("eventFileName");
        }

    }
}
