package com.xinyilu.system.checkreport;

import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.utils.jreechart.FreeChartUtil;
import com.xinyilu.common.utils.jreechart.GenerateBarChartUtil;
import com.xinyilu.common.utils.jreechart.PdfUtils;
import com.xinyilu.system.domain.dto.CheckReportDTO;
import com.xinyilu.system.domain.vo.TestItemAvgScoreVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.AllClassByVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.AllStudentScoreVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.TestAllStudentScoreVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.TestAllStudentScoresVO;
import com.xinyilu.system.domain.vo.averageHeightAndWeight.AverageHeightAndWeightVO;
import com.xinyilu.system.domain.vo.averageHeightAndWeight.HeightAndWeightAvgScoreVO;
import com.xinyilu.system.domain.vo.kinderPhysiqueAnalysis.*;
import com.xinyilu.system.domain.vo.kindergartenSideAnalysis.KindergartenSideAnalysisVO;
import com.xinyilu.system.domain.vo.physicalActionAnalysis.PhysicalActionAnalysisVO;
import com.xinyilu.system.domain.vo.physicalActionAnalysis.PhysicalActionVO;
import com.xinyilu.system.domain.vo.testItemAvgScore.ClassAvgCategoryScoreVO;
import com.xinyilu.system.domain.vo.testItemAvgScore.TestItemAvgScoreClassVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CenterTextMode;
import org.jfree.chart.plot.RingPlot;
import org.jfree.chart.plot.SpiderWebPlot;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 幼儿园综合体质报告工具类
 * @Author wh
 * @Date 2022-09-23 16:18:11
 * @Version 1.0
 */
@Component
@Slf4j
public class KindConstitutionCheckReport {

    /**
     * 幼儿园综合得分标题
     */
    private static final String COMPREHENSIVE_HEAD_TITLE = "本园幼儿综合体质评估综合得分";

    /**
     * 动作发展状况
     */
    private static final String Motor_DEVELOPMENT_HEAD_TITLE = "动作发展状况";

    /**
     * 动作发展状况
     */
    private static final String CLASS_COMPREHENSIVE_HEAD_TITLE = "班级体质分析";

    /**
     * 综合体质分析图标题
     */
    private static final String ANALYSIS_PICTURE_HEAD_TITLE = "综合体质分析图";

    /**
     * 综合体质分析标题
     */
    private static final String ANALYSIS_HEAD_TITLE = "综合体质分析";

    /**
     * 平均身高体重标题
     */
    private static final String AVERAGE_HEIGHT_AND_WEIGHT = "平均身高体重";

    /**
     * 体测达标分析标题
     */
    private static final String BODY_SIDE_PROFILE_ANALYSIS = "体测概况分析";

    /**
     * 体测达标分析标题
     */
    private static final String PHYSICAL_ANALYSIS_HEAD = "体测达标分析";

    /**
     * 本园体测成绩达标率(%)环形图标题
     */
    private static final String PHYSICAL_STRENGTH_AGE_GROUP_ALL_CIRCULAR_GRAPH = "本园体测成绩达标率(%)";
    /**
     * 全国优秀幼儿榜(TOP10)标题
     */
    private static final String NATIONAL_OUTSTANDING_CHILDREN_TEN = "全园优秀幼儿榜(TOP10)";
    /**
     * 班级优秀幼儿榜标题
     */
    private static final String National_Excellent_Children = "班级优秀幼儿榜";
    /**
     * 班级优秀幼儿榜标题
     */
    private static final String CLASS_COMPREHENSIVE_TEST_RESULTS = "班级综合体测成绩排名";

    /**
     * 固定高
     */
    public static float fixedHeight = 27f;

    /**
     * 幼儿园综合体质信息/动作发展状况
     *
     * @param checkReport 幼儿园综合体质信息
     * @throws Exception 异常信息
     */
    public static void createKindergartenCheckReportMale(CheckReportDTO checkReport) throws Exception {
        log.info("开始生成测试批次报告，批次编号为：[{}]", checkReport.getBatchCode());
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, checkReport.getOutputStream());
        //设置图片是否错乱问题
        writer.setStrictImageSequence(true);
        document.setPageSize(PageSize.A4);
        document.setMargins(50, 50, 50, 50);
        String title = Constants.KINDERGARTEN_CONSTITUTION_CHECK_REPORT_NAME;
        //打开文档，只有打开后才能往里面加东西
        document.open();
        document.addTitle(title);
        //设置报告开头的标题和创建时间
        Paragraph titleParagraph = createFirstHead(title);
        document.add(titleParagraph);
        //二级标题
        Paragraph studentInfoTitleParagraph = createHeadInfo("幼儿园: " + checkReport.getKindergartenName());
        document.add(studentInfoTitleParagraph);
        //体侧达标分析
        setKindergarten(document, checkReport.getKindergartenSideAnalysisVO());
        //设置本园参加体测各年龄阶段人数分部柱状图
        setNumberOfPeopleAge(document, checkReport.getKindergartenSideAnalysisVO());
        // 设置本园体测成绩达标率环形图
        setPhysicalStrengthAgeGroupAllCircularGraph(document, checkReport.getKindergartenSideAnalysisVO());
        //体侧概况分析
        // 全国优秀幼儿榜(TOP10)
        setNationalOutstandingChildren(document, checkReport.getTestAllStudentScoreVO());
        //班级优秀幼儿榜
        setNationalExcellentChildren(document, checkReport.getTestAllStudentScoreVO());
        //班级综合体测成绩排名
        setClassComprehensiveTests(document, checkReport.getTestAllStudentScoreVO());
        //设置幼儿园平均身高体重
        generateBarChartPicture(document, checkReport.getAverageHeightAndWeightVO());
        if (Objects.nonNull(checkReport.getMaleInfo()) || Objects.nonNull(checkReport.getFemaleInfo())) {
            //设置综合得分标题
            Paragraph zongHeTitleParagraph = createHeadInfo(KindConstitutionCheckReport.ANALYSIS_HEAD_TITLE);
            document.add(zongHeTitleParagraph);
        }
        //幼儿综合得分(男)
        setComprehensiveScore(document, "男", checkReport.getMaleInfo());
        //综合体质分析图(男)
        createPhysiqueAnalysisPicture(document, checkReport.getMaleInfo());
        buildRiskIndicatorMale(document, checkReport.getMaleInfo());
        //幼儿综合得分(女)
        setComprehensiveScore(document, "女", checkReport.getFemaleInfo());
        //综合体质分析图(女)
        createPhysiqueAnalysisPicture(document, checkReport.getFemaleInfo());
        buildRiskIndicatorMale(document, checkReport.getFemaleInfo());
        //设置动作发展状况
        if (CollectionUtils.isNotEmpty(checkReport.getPhysicalActionList())) {
            //设置综合得分标题
            Paragraph zongHeTitleParagraph = createHeadInfo(KindConstitutionCheckReport.Motor_DEVELOPMENT_HEAD_TITLE);
            document.add(zongHeTitleParagraph);
            for (PhysicalActionVO physicalActionVO : checkReport.getPhysicalActionList()) {
                if (Objects.nonNull(physicalActionVO.getClassTypeName())) {
                    buildActionMale(document, physicalActionVO);
                }
            }
        }
        //生成班级体质报告
        if (CollectionUtils.isNotEmpty(checkReport.getCategoryScoreList())) {
            //设置级体质报告
            Paragraph zongHeTitleParagraph = createHeadInfo(KindConstitutionCheckReport.CLASS_COMPREHENSIVE_HEAD_TITLE);
            document.add(zongHeTitleParagraph);
            //生成体质表格
            for (ClassAvgCategoryScoreVO classAvgCategoryScoreVO : checkReport.getCategoryScoreList()) {
                buildClassIndicatorMale(document, classAvgCategoryScoreVO);
                //生成柱状图
                createChildrenRankBarPicture(document, classAvgCategoryScoreVO);
            }
        }
        document.close();
        writer.close();
        log.info("结束生成测试批次报告，批次编号为：[{}]", checkReport.getBatchCode());
    }

    /**
     * 创建学生综合分析各测试项目成绩对比柱状图
     *
     * @param document        文档对象
     * @param childrenRanking 排序信息
     * @throws Exception 异常信息
     */
    private static void createChildrenRankBarPicture(Document document, ClassAvgCategoryScoreVO childrenRanking) throws Exception {
        if (CollectionUtils.isNotEmpty(childrenRanking.getCategoryScoreList())) {
            //x轴名称列表
            List<String> xAxisNameList = new ArrayList<>();
            List<String> legendNameList = new ArrayList<>();
            childrenRanking.getCategoryScoreList().get(0).getCategoryScoreList().forEach(item -> legendNameList.add(item.getCategoryName()));
            //数据格式
            Map<String, List<Object>> map = new HashMap<>();
            List<BigDecimal> dataList = new ArrayList<>();
            for (TestItemAvgScoreVO scoreInfoVO : childrenRanking.getCategoryScoreList()) {
                if (StringUtils.isNotBlank(scoreInfoVO.getClassName())) {
                    xAxisNameList.add(scoreInfoVO.getClassName());
                    scoreInfoVO.getCategoryScoreList().forEach(item -> dataList.add(item.getAvgScore()));
                    Map<String, List<TestItemAvgScoreClassVO>> listMap = scoreInfoVO.getCategoryScoreList().stream().collect(Collectors.groupingBy(TestItemAvgScoreClassVO::getCategoryName));
                    for (String categoryName : listMap.keySet()) {
                        if (Objects.isNull(map.get(categoryName))) {
                            List<Object> list = new ArrayList<>();
                            listMap.get(categoryName).forEach(item -> list.add(item.getAvgScore()));
                            map.put(categoryName, list);
                        } else {
                            listMap.get(categoryName).forEach(item -> map.get(categoryName).add(item.getAvgScore()));
                        }
                    }
                }
            }
            List<List<Object>> list = new ArrayList<>();
            for (String s : legendNameList) {
                list.add(map.get(s));
            }
            //图例背景颜色
            List<Color> legendColorList = new ArrayList<>(Collections.singletonList(new Color(248, 99, 134)));
            BigDecimal maxScore = BigDecimal.ZERO;
            if (CollectionUtils.isNotEmpty(dataList)) {
                maxScore = Collections.max(dataList);
            }
            JFreeChart chart = GenerateBarChartUtil.createBarChart("", legendNameList, xAxisNameList
                    , list, FreeChartUtil.createChartTheme("宋体"), "", "",
                    0d, maxScore.doubleValue(), legendColorList, true, "{2}");
            savePictureToDocument(document, chart, "");
        }
    }

    /**
     * 本园参加体测各年龄阶段人数分部图 柱状图
     *
     * @param document                   文本对象
     * @param kindergartenSideAnalysisVO 幼儿园数据
     * @return void
     **/
    public static void setNumberOfPeopleAge(Document document, KindergartenSideAnalysisVO kindergartenSideAnalysisVO) throws Exception {
        if (Objects.nonNull(kindergartenSideAnalysisVO)) {
            //x轴名称列表
            String studentFeMaleType = "女";
            String studentMaleType = "男";
            java.util.List<String> xAxisNameList = new ArrayList<>(Arrays.asList("3岁-4岁", "4岁-5岁", "5岁-6岁", "6岁以上"));
            //图例名称列表
            java.util.List<String> legendNameList = new ArrayList<>(Arrays.asList(studentFeMaleType, studentMaleType));
            //数据集合
            List<List<Object>> dataList = Lists.newArrayList();
            dataList.add(new ArrayList<>(Arrays.asList(kindergartenSideAnalysisVO.getThreeAndFourMaleCount(),
                    kindergartenSideAnalysisVO.getFourAndFiveMaleCount(),
                    kindergartenSideAnalysisVO.getFiveAndSixMaleCount(),
                    kindergartenSideAnalysisVO.getSixAndMoreMaleCount())));
            dataList.add(new ArrayList<>(Arrays.asList(kindergartenSideAnalysisVO.getThreeAndFourFeMaleCount(),
                    kindergartenSideAnalysisVO.getFourAndFiveFeMaleCount(),
                    kindergartenSideAnalysisVO.getFiveAndSixFeMaleCount(),
                    kindergartenSideAnalysisVO.getSixAndMoreFeMaleCount())));
            // 获取最大分数
            List<Double> scoreList = Arrays.asList(kindergartenSideAnalysisVO.getThreeAndFourMaleCount(),
                    kindergartenSideAnalysisVO.getFourAndFiveMaleCount(),
                    kindergartenSideAnalysisVO.getFiveAndSixMaleCount(),
                    kindergartenSideAnalysisVO.getSixAndMoreMaleCount(),
                    kindergartenSideAnalysisVO.getThreeAndFourFeMaleCount(),
                    kindergartenSideAnalysisVO.getFourAndFiveFeMaleCount(),
                    kindergartenSideAnalysisVO.getFiveAndSixFeMaleCount(),
                    kindergartenSideAnalysisVO.getSixAndMoreFeMaleCount());
            Double maxScore = 0.0;
            if (CollectionUtils.isNotEmpty(scoreList)) {
                maxScore = Collections.max(scoreList);
            }
            //图例背景颜色
            List<Color> legendColorList = new ArrayList<>(Collections.singletonList(new Color(65, 105, 225)));
            JFreeChart chart = GenerateBarChartUtil.createBarChart("", legendNameList, xAxisNameList
                    , dataList, FreeChartUtil.createChartTheme("宋体"), "y轴", "x轴",
                    0d, maxScore, legendColorList, true, "{2}");
            savePictureToDocument(document, chart, "");
        }
    }

    /**
     * 本园体测成绩达标率(%)环形图
     *
     * @param document                   文件信息
     * @param kindergartenSideAnalysisVO 幼儿园信息
     * @return void
     **/
    public static void setPhysicalStrengthAgeGroupAllCircularGraph(Document document, KindergartenSideAnalysisVO kindergartenSideAnalysisVO) throws Exception {
        if (Objects.nonNull(kindergartenSideAnalysisVO) && (Objects.nonNull(kindergartenSideAnalysisVO.getStandardRate()))) {
            //使用JFreeChart生成本园体测成绩达标率环形图
            DefaultPieDataset dataSet = new DefaultPieDataset();
            //使用循环向数据集合中添加数据
            int i, j;
            String[] a = {"<60不合格", "60-80合格", ">80优秀"};
            BigDecimal[] b = {kindergartenSideAnalysisVO.getUnQualifyRate(),
                    kindergartenSideAnalysisVO.getQualifyRate(),
                    kindergartenSideAnalysisVO.getExcellentRate()};
            for (i = 0, j = 0; i < a.length && j < b.length; i++, j++) {
                dataSet.setValue(a[i], b[j]);
            }
            StandardChartTheme mChartTheme = new StandardChartTheme("CN");
            mChartTheme.setLargeFont(new java.awt.Font("黑体", java.awt.Font.BOLD, 14));
            mChartTheme.setExtraLargeFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 20));
            //应用主题样式
            ChartFactory.setChartTheme(mChartTheme);
            JFreeChart chart = ChartFactory.createRingChart(PHYSICAL_STRENGTH_AGE_GROUP_ALL_CIRCULAR_GRAPH, dataSet, true, false, false);
            //图表
            RingPlot ringplot = (RingPlot) chart.getPlot();
            ringplot.setLabelFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 14));
            ringplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{1}"));
            //设置环形图中心文字
            String centerText = "达标率：" + kindergartenSideAnalysisVO.getStandardRate() + "%";
            ringplot.setCenterTextMode(CenterTextMode.FIXED);
            ringplot.setCenterText(centerText);
            ringplot.setSimpleLabels(true);
            //标题
            TextTitle texttitle = chart.getTitle();
            texttitle.setFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 30));
            //图示
            LegendTitle legendtitle = chart.getLegend();
            legendtitle.setItemFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 14));
            savePictureToDocument(document, chart, PHYSICAL_STRENGTH_AGE_GROUP_ALL_CIRCULAR_GRAPH);
            //创建空段落，解决图片和表格之间的覆盖问题
            Paragraph body = createEmptyHeadInfo();
            document.add(body);
        }
    }

    /**
     * 平均身高体重
     *
     * @param document                 文件对象
     * @param averageHeightAndWeightVO 输入参数
     * @throws Exception 异常信息
     */
    public static void generateBarChartPicture(Document document, List<AverageHeightAndWeightVO> averageHeightAndWeightVO) throws Exception {
        if (CollectionUtils.isNotEmpty(averageHeightAndWeightVO)) {
            Paragraph childrenRankParagraph = createHeadInfo(KindConstitutionCheckReport.AVERAGE_HEIGHT_AND_WEIGHT);
            document.add(childrenRankParagraph);
            //x轴集合
            List<String> xAxisNameList = new ArrayList<>();
            //图例名称列表集合
            List<String> legendNameList = Arrays.asList("男", "女");
            //图例名称列表集合
            List<String> sexList = Arrays.asList("MALE", "FEMALE");
            //体重和身高的数据
            Map<String, List<HeightAndWeightAvgScoreVO>> heightAndWeightAvgScoreMap = new HashMap<>();
            //图列名称集合
            for (AverageHeightAndWeightVO averageHeightAndWeight : averageHeightAndWeightVO) {
                //获取班级类型
                xAxisNameList.add(averageHeightAndWeight.getClassName());
                //体重和身高的分组
                Map<String, List<HeightAndWeightAvgScoreVO>> collect = averageHeightAndWeight.getWeightAndHeightAvgScoreList().stream()
                        .filter(Objects::nonNull)
                        .collect(Collectors.groupingBy(HeightAndWeightAvgScoreVO::getItemCode));
                //身高体重分组数据
                for (String key : collect.keySet()) {
                    if (CollectionUtils.isEmpty(heightAndWeightAvgScoreMap.get(key))) {
                        List<HeightAndWeightAvgScoreVO> list = new ArrayList<>();
                        CollectionUtils.addAll(list, collect.get(key));
                        heightAndWeightAvgScoreMap.put(key, list);
                    } else {
                        List<HeightAndWeightAvgScoreVO> heightAndWeightAvgScoreVOList = heightAndWeightAvgScoreMap.get(key);
                        heightAndWeightAvgScoreVOList.addAll(collect.get(key));
                        heightAndWeightAvgScoreMap.put(key, heightAndWeightAvgScoreVOList);
                    }
                }
            }
            //身高和体重生成两个 柱状图
            for (String heightOrWeightAvgScore : heightAndWeightAvgScoreMap.keySet()) {
                //排序的获取最大值
                List<BigDecimal> bigDecimalList = new ArrayList<>();
                //数据集合
                List<List<Object>> dataList = new ArrayList<>();
                List<HeightAndWeightAvgScoreVO> heightOrWeightAvgScoreList = heightAndWeightAvgScoreMap.get(heightOrWeightAvgScore);
                Map<String, List<HeightAndWeightAvgScoreVO>> collect = heightOrWeightAvgScoreList.stream().collect(Collectors.groupingBy(HeightAndWeightAvgScoreVO::getStudentSex));
                for (String sex : sexList) {
                    List<Object> objectList = new ArrayList<>();
                    if (Objects.nonNull(collect.get(sex))) {
                        collect.get(sex).forEach(item -> objectList.add(item.getAverageScore()));
                        collect.get(sex).forEach(item -> bigDecimalList.add(item.getAverageScore()));
                    }
                    dataList.add(objectList);
                }
                //最大值
                BigDecimal maxScore = BigDecimal.ZERO;
                if (CollectionUtils.isNotEmpty(bigDecimalList)) {
                    maxScore = Collections.max(bigDecimalList);
                }
                //图例背景颜色
                if (xAxisNameList.size() > 0 && legendNameList.size() > 0) {
                    List<Color> legendColorList = new ArrayList<>(Collections.singletonList(new Color(248, 99, 134)));
                    JFreeChart chart = GenerateBarChartUtil.createBarChart("各年级男/女平均" + (heightOrWeightAvgScore.equals("W001") ? "体重" : "身高"), legendNameList, xAxisNameList
                            , dataList, FreeChartUtil.createChartTheme("宋体"), "", "",
                            0d, maxScore.doubleValue(), legendColorList, true, "{2}");
                    savePictureToDocument(document, chart, "");
                }
            }
        }
    }

    /**
     * 设置一级标题
     *
     * @param title 标题内容
     * @return 标题段落
     */
    private static Paragraph createFirstHead(String title) throws Exception {
        Font font = createFont(22, Font.BOLD);
        Paragraph paragraph = new Paragraph(title, font);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }

    /**
     * 根据传入的参数生成PDF文档使用的字体
     *
     * @param fontSize 字体大小
     * @param fontMode 字体正常、加粗、下划线等
     * @return 返回生成的字体
     */
    private static Font createFont(int fontSize, int fontMode) throws Exception {
        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        return new Font(bfChinese, fontSize, fontMode, BaseColor.BLACK);
    }

    /**
     * 二级标题
     *
     * @param headTitle 二级标题名称
     * @return 时间的段落
     */
    private static Paragraph createHeadInfo(String headTitle) throws Exception {
        Font font = createFont(14, Font.BOLD);
        Paragraph paragraph = new Paragraph(headTitle, font);
        paragraph.setSpacingAfter(10);
        paragraph.setSpacingBefore(10);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }

    /**
     * 二级标题
     *
     * @param headTitle 二级标题名称
     * @return 时间的段落
     */
    private static Paragraph createHeadThreeInfo(String headTitle) throws Exception {
        Font font = createFont(14, Font.BOLD);
        font.setStyle(0);
        Paragraph paragraph = new Paragraph(headTitle, font);
        paragraph.setSpacingAfter(10);
        paragraph.setSpacingBefore(10);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }

    /**
     * 设置综合得分
     *
     * @param document 文档对象
     * @throws Exception 异常信息
     */
    private static void setComprehensiveScore(Document document,
                                              String studentSex,
                                              KinderPhysiqueAnalysisVO kinderPhysiqueAnalysis) throws Exception {
        //设置综合得分成绩
        if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysis.getFirstCategoryScoreList())) {
            //设置综合得分标题
            Paragraph studentInfoTitleParagraph = createHeadThreeInfo(KindConstitutionCheckReport.COMPREHENSIVE_HEAD_TITLE + "(" + studentSex + ")");
            document.add(studentInfoTitleParagraph);
            //每个分类的得分信息
            StringBuilder comprehensiveScore = new StringBuilder();
            BigDecimal sum = new BigDecimal(0);
            for (FirstCategoryScoreVO categoryVO : kinderPhysiqueAnalysis.getFirstCategoryScoreList()) {
                String categoryName = StringUtils.isBlank(categoryVO.getCategoryName()) ? "" : categoryVO.getCategoryName();
                BigDecimal categoryScore = Objects.isNull(categoryVO.getAvgCategoryFraction()) ? BigDecimal.ZERO : categoryVO.getAvgCategoryFraction();
                sum = sum.add(categoryScore);
                comprehensiveScore.append(categoryName).append("(").append(categoryScore).append(")").append("   +");
            }
            String comprehensiveStr = comprehensiveScore.substring(0, comprehensiveScore.length() - 1);
            comprehensiveStr = "  " + comprehensiveStr + "  =  综合得分(" + sum + ")";
            Font font = createFont(12, Font.NORMAL);
            Paragraph comprehensiveParagraph = new Paragraph(comprehensiveStr, font);
            comprehensiveParagraph.setSpacingAfter(10);
            comprehensiveParagraph.setSpacingBefore(10);
            comprehensiveParagraph.setAlignment(Element.ALIGN_CENTER);
            document.add(comprehensiveParagraph);
        }
    }

    /**
     * 生成学生个人综合分析雷达图
     *
     * @param document         文本对象
     * @param physiqueAnalysis 个人分析数据
     * @throws Exception 异常信息
     */
    private static void createPhysiqueAnalysisPicture(Document document, KinderPhysiqueAnalysisVO physiqueAnalysis) throws Exception {
        //生成综合分析体质雷达图
        if (CollectionUtils.isNotEmpty(physiqueAnalysis.getCategoryScoreList())) {
            //设置综合体质分析图标题
            Paragraph analysisTitleParagraph = createHeadThreeInfo(ANALYSIS_PICTURE_HEAD_TITLE);
            document.add(analysisTitleParagraph);
            //设置数据
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            for (KinderCategoryScoreVO categoryVO : physiqueAnalysis.getCategoryScoreList()) {
                //分类名称
                String categoryName = StringUtils.isBlank(categoryVO.getCategoryName()) ? "无" : categoryVO.getCategoryName();
                //分类分类级别描述
                String levelName = StringUtils.isBlank(categoryVO.getAvgCategoryName()) ? "无" : categoryVO.getAvgCategoryName();
                //得分
                BigDecimal categoryScore = Objects.isNull(categoryVO.getItemFraction()) ? BigDecimal.ZERO : categoryVO.getItemFraction();
                dataset.addValue(categoryScore.doubleValue(), categoryName, categoryScore + " (" + levelName + ")");
            }
            //创建雷达图并将雷达图写入到PDF文档中
            SpiderWebPlot spiderwebplot = new SpiderWebPlot(dataset);
            LegendTitle legendtitle = new LegendTitle(spiderwebplot);
            legendtitle.setPosition(RectangleEdge.TOP);
            JFreeChart chart = new JFreeChart(ANALYSIS_PICTURE_HEAD_TITLE, TextTitle.DEFAULT_FONT, spiderwebplot, false);
            chart.addSubtitle(legendtitle);
            savePictureToDocument(document, chart, ANALYSIS_PICTURE_HEAD_TITLE);
        }
    }

    /**
     * 将JFreeChart生成的图片保存到PDF文档中公共方法
     *
     * @param document    文档对象
     * @param chart       图片对象
     * @param pictureName 图片名称
     * @throws Exception 异常信息
     */
    private static void savePictureToDocument(Document document, JFreeChart chart, String pictureName) throws Exception {
        log.info("开始保存图片到PDF文档中，图片名称为：[{}]", pictureName);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ChartUtils.writeChartAsJPEG(outputStream, chart, 800, 600);
        Image image = Image.getInstance(outputStream.toByteArray());
        image.setAlignment(Image.ALIGN_CENTER);
        image.scaleAbsolute(500, 300);
        document.add(image);
        log.info("完成保存图片到PDF文档中，图片名称为：[{}]", pictureName);
    }


    /**
     * 综合体质分析图(年龄表格图)
     *
     * @param document                 文档对象
     * @param kinderPhysiqueAnalysisVO 输入参数
     * @throws Exception 异常信息
     */
    public static void buildRiskIndicatorMale(Document document, KinderPhysiqueAnalysisVO kinderPhysiqueAnalysisVO) throws Exception {
        if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysisVO.getCategoryScoreList())) {
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bfChinese);
            //表头数量:项目名称+年龄+平均分数
            PdfPTable table = PdfUtils.createPdfTable(kinderPhysiqueAnalysisVO.getCategoryScoreList().size() + 2);
            table.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table.setWidthPercentage(100);
            List<String> rowName = new ArrayList<>();
            rowName.add("年龄");
            rowName.add("平均总分");
            if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysisVO.getCategoryTableNameList())) {
                for (CategoryTableName categoryTableName : kinderPhysiqueAnalysisVO.getCategoryTableNameList()) {
                    for (ChildrenTableName childrenTableName : categoryTableName.getChildrenTableNameList()) {
                        rowName.add(childrenTableName.getCategoryName());
                    }
                }
            }
            List<CategoryScoreVO> categoryAgeFractionList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysisVO.getCategoryAgeFractionList())) {
                categoryAgeFractionList = kinderPhysiqueAnalysisVO.getCategoryAgeFractionList();
            }
            dataProcessingMale(rowName.toArray(new String[]{}), document, table, rowName, categoryAgeFractionList, font, kinderPhysiqueAnalysisVO.getCategoryTableNameList());
        }
    }


    /**
     * 综合体质分析图(年龄表格图)
     *
     * @param document                 文档对象
     * @param kinderPhysiqueAnalysisVO 输入参数
     * @throws Exception 异常信息
     */
    public static void buildClassIndicatorMale(Document document, ClassAvgCategoryScoreVO kinderPhysiqueAnalysisVO) throws Exception {
        if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysisVO.getCategoryScoreList())) {
            //设置综合得分标题
            Paragraph motorDevelopmentParagraph = createHeadThreeInfo(KindConstitutionCheckReport.CLASS_COMPREHENSIVE_HEAD_TITLE + "(" + (StringUtils.isNotBlank(kinderPhysiqueAnalysisVO.getCategoryScoreList().get(0).getClassName()) ? kinderPhysiqueAnalysisVO.getCategoryScoreList().get(0).getClassName() : "") + ")");
            document.add(motorDevelopmentParagraph);
            List<String> rowName = new ArrayList<>();
            rowName.add("年龄");
            rowName.add("平均总分");
            List<String> rowCount = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(kinderPhysiqueAnalysisVO.getCategoryTableNameList())) {
                for (CategoryTableName categoryTableName : kinderPhysiqueAnalysisVO.getCategoryTableNameList()) {
                    for (ChildrenTableName childrenTableName : categoryTableName.getChildrenTableNameList()) {
                        rowName.add(childrenTableName.getCategoryName());
                        rowCount.add(childrenTableName.getCategoryName());
                    }
                }
            }
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bfChinese);
            //表头数量:项目名称+年龄+平均分数
            PdfPTable table = PdfUtils.createPdfTable(rowCount.size() + 2);
            table.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table.setWidthPercentage(100);
            List<TestItemAvgScoreVO> categoryScoreList = kinderPhysiqueAnalysisVO.getCategoryScoreList();
            dataClassMale(rowName.toArray(new String[]{}), document, table, rowName, categoryScoreList, font, kinderPhysiqueAnalysisVO.getCategoryTableNameList());
        }
    }

    /**
     * 生成动作发展状况表格
     *
     * @param document   文档对象
     * @param largeClass 输入参数
     * @throws Exception 异常信息
     */
    public static void buildActionMale(Document document, PhysicalActionVO largeClass) throws Exception {
        //设置综合得分标题
        Paragraph motorDevelopmentParagraph = createHeadThreeInfo(KindConstitutionCheckReport.Motor_DEVELOPMENT_HEAD_TITLE + "(" + (StringUtils.isNotBlank(largeClass.getClassTypeName()) ? largeClass.getClassTypeName() : "") + ")");
        document.add(motorDevelopmentParagraph);
        //创建表格
        PdfPTable table = createTable(largeClass);
        for (PhysicalActionAnalysisVO physicalActionAnalysisVO : largeClass.getPhysicalActionList()) {
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getItemName()) ? physicalActionAnalysisVO.getItemName() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getMaleAvgScore()) ? physicalActionAnalysisVO.getMaleAvgScore().toString() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getMaleCityAvgScore()) ? physicalActionAnalysisVO.getMaleCityAvgScore().toString() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getMalePassCount()) ? physicalActionAnalysisVO.getMalePassCount().toString() : ""));
            table.addCell(createTableContent((Objects.nonNull(physicalActionAnalysisVO.getMalePassRate()) ? physicalActionAnalysisVO.getMalePassRate().toString() + "%" : "")));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getFeMaleAvgScore()) ? physicalActionAnalysisVO.getFeMaleAvgScore().toString() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getFeMaleCityAvgScore()) ? physicalActionAnalysisVO.getFeMaleCityAvgScore().toString() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getFeMalePassCount()) ? physicalActionAnalysisVO.getFeMalePassCount().toString() : ""));
            table.addCell(createTableContent(Objects.nonNull(physicalActionAnalysisVO.getFeMalePassRate()) ? physicalActionAnalysisVO.getFeMalePassRate().toString() + "%" : ""));
        }
        document.add(table);
    }

    /**
     * 设置动作发展状况的单元格
     *
     * @param largeClass 班级类型
     * @return PdfPTable 表格对象
     * @throws Exception 异常信息
     */
    public static PdfPTable createTable(PhysicalActionVO largeClass) throws Exception {
        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        PdfPTable table = PdfUtils.createPdfTable(9);
        table.setSpacingBefore(20f);
        // 设置表格宽度为100%
        table.setWidthPercentage(100);
        Font font = new Font(bfChinese);
        PdfPCell cell = new PdfPCell(new Phrase(largeClass.getClassTypeName(), font));
        cell.setColspan(9);//合并单元格
        cell.setMinimumHeight(20);
        cell.setUseAscender(true);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.addCell(cell);
        PdfPCell cellProject = new PdfPCell(new Phrase("项目", font));
        cellProject.setRowspan(2);//合并单元格
        cellProject.setMinimumHeight(20);
        cellProject.setUseAscender(true);
        cellProject.setHorizontalAlignment(Element.ALIGN_CENTER);
        cellProject.setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.addCell(cellProject);
        PdfPCell cellman = new PdfPCell(new Phrase("男孩", font));
        cellman.setColspan(4);//合并单元格
        cellman.setMinimumHeight(20);
        cellman.setUseAscender(true);
        cellman.setHorizontalAlignment(Element.ALIGN_CENTER);
        cellman.setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.addCell(cellman);
        PdfPCell cellWoman = new PdfPCell(new Phrase("女孩", font));
        cellWoman.setColspan(4);//合并单元格
        cellWoman.setMinimumHeight(20);
        cellWoman.setUseAscender(true);
        cellWoman.setHorizontalAlignment(Element.ALIGN_CENTER);
        cellWoman.setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.addCell(cellWoman);
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "平均值", "全市平均值", "合格人数", "合格率", "平均值", "全市平均值", "合格人数", "合格率");
        for (String s : list) {
            PdfPCell cell1 = new PdfPCell(new Phrase(s, font));
            cell1.setMinimumHeight(20);
            cell1.setUseAscender(true);
            cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
            table.addCell(cell1);
        }
        return table;
    }

    /**
     * 数据处理
     *
     * @param headers               头部
     * @param document              文档对象
     * @param table                 表格信息
     * @param row                   行数
     * @param list                  数据
     * @param font                  字体
     * @param categoryTableNameList 表头明细
     * @throws Exception 异常信息
     */
    public static void dataProcessingMale(String[] headers, Document document, PdfPTable table, List<String> row, List<CategoryScoreVO> list, Font font, List<CategoryTableName> categoryTableNameList) throws Exception {
        //年龄和平均分数的空格
        PdfPCell cell = new PdfPCell(new Phrase("年龄", font));
        cell.setMinimumHeight(20);
        cell.setUseAscender(true);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setRowspan(2);//合并单元格
        table.addCell(cell);
        //年龄和平均分数的空格
        PdfPCell cell3 = new PdfPCell(new Phrase("平均总分", font));
        cell3.setMinimumHeight(20);
        cell3.setUseAscender(true);
        cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell3.setRowspan(2);//合并单元格
        table.addCell(cell3);
        if (CollectionUtils.isNotEmpty(categoryTableNameList)) {
            for (CategoryTableName categoryTableName : categoryTableNameList) {
                PdfPCell cell1 = new PdfPCell(new Phrase(categoryTableName.getParentName(), font));
                cell1.setColspan(categoryTableName.getChildrenTableNameList().size());//合并单元格
                cell1.setMinimumHeight(20);
                cell1.setUseAscender(true);
                cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                table.addCell(cell1);
            }
        }
        if (headers.length > 2) {
            for (int i = 2; i < headers.length; i++) {
                table.addCell(createTableContent(headers[i]));
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            for (CategoryScoreVO categoryScoreVO : list) {
                //默认不跨行、跨列
                table.addCell(createTableContent(categoryScoreVO.getStudentAge()));
                table.addCell(createTableContent(categoryScoreVO.getTotalAvgFraction().toString()));
                Map<String, BigDecimal> map = categoryScoreVO.getCategoryAvgFractionList().stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getCategoryName())).collect(Collectors.toMap(FirstCategoryScoreVO::getCategoryName, FirstCategoryScoreVO::getAvgCategoryFraction));
                for (int i = 2; i < row.size(); i++) {
                    table.addCell(createTableContent(map.getOrDefault(row.get(i), BigDecimal.ZERO).toString()));
                }
            }
        }
        document.add(table);
    }


    /***
     * @Description :数据处理
     * @param headers               头部
     * @param document              文档对象
     * @param table                 表格信息
     * @param row                   行数
     * @param list                  数据
     * @param font                  字体
     * @throws Exception 异常信息
     */
    public static void dataClassMale(String[] headers, Document document, PdfPTable table, List<String> row, List<TestItemAvgScoreVO> list, Font font, List<CategoryTableName> categoryTableNameList) throws Exception {
        //年龄和平均分数的空格
        PdfPCell cell = new PdfPCell(new Phrase("年龄", font));
        cell.setMinimumHeight(20);
        cell.setUseAscender(true);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setRowspan(2);//合并单元格
        table.addCell(cell);
        //年龄和平均分数的空格
        PdfPCell cell3 = new PdfPCell(new Phrase("平均总分", font));
        cell3.setMinimumHeight(20);
        cell3.setUseAscender(true);
        cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell3.setRowspan(2);//合并单元格
        table.addCell(cell3);
        if (CollectionUtils.isNotEmpty(categoryTableNameList)) {
            for (CategoryTableName categoryTableName : categoryTableNameList) {
                PdfPCell cell1 = new PdfPCell(new Phrase(categoryTableName.getParentName(), font));
                cell1.setColspan(categoryTableName.getChildrenTableNameList().size());//合并单元格
                cell1.setMinimumHeight(20);
                cell1.setUseAscender(true);
                cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                table.addCell(cell1);
            }
        }
        if (headers.length > 2) {
            for (int i = 2; i < headers.length; i++) {
                table.addCell(createTableContent(headers[i]));
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            for (TestItemAvgScoreVO categoryScoreVO : list) {
                //默认不跨行、跨列
                table.addCell(createTableContent(categoryScoreVO.getClassName()));
                table.addCell(createTableContent(categoryScoreVO.getTotalAvScore().toString()));
                Map<String, BigDecimal> map = categoryScoreVO.getCategoryScoreList().stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getCategoryName())).collect(Collectors.toMap(TestItemAvgScoreClassVO::getCategoryName, TestItemAvgScoreClassVO::getAvgScore));
                for (int i = 2; i < row.size(); i++) {
                    table.addCell(createTableContent(map.getOrDefault(row.get(i), new BigDecimal(0)).toString()));
                }
            }
        }
        document.add(table);
    }

    /**
     * 创建表格内容
     *
     * @param title 标题
     * @return PdfPCell 列
     * @throws Exception 异常信息
     */
    private static PdfPCell createTableContent(String title) throws Exception {
        Font font = createFont(10, Font.NORMAL);
        PdfPCell cell = new PdfPCell(new Phrase(title, font));
        cell.setMinimumHeight(20);
        cell.setUseAscender(true);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        return cell;
    }

    /**
     * 设置标题
     *
     * @param document              文件
     * @param testAllStudentScoreVO 表格信息集合
     * @return void
     **/
    public static void setNationalOutstandingChildren(Document document, TestAllStudentScoresVO testAllStudentScoreVO) throws Exception {
        //二级标题
        Paragraph studentInfoTitleParagraph = createHeadInfo(BODY_SIDE_PROFILE_ANALYSIS);
        document.add(studentInfoTitleParagraph);
        if (CollectionUtils.isNotEmpty(testAllStudentScoreVO.getTestAllStudentScoreVOList())) {
            //表头内容
            List<String> tableHeadList = Arrays.asList("姓名", "班级", "分数");
            //创建表格头并设置表格头部元素信息
            PdfPTable physicalSubstanceTable = createTableInfo(document, NATIONAL_OUTSTANDING_CHILDREN_TEN, 3, tableHeadList);
            //填充表格其余元素信息
            nationalOutstandingChildren(physicalSubstanceTable, testAllStudentScoreVO);
            document.add(physicalSubstanceTable);
        }
    }

    /**
     * 设置表格的头
     *
     * @param document              文件
     * @param testAllStudentScoreVO 所有学生信息
     * @return void
     **/
    public static void setNationalExcellentChildren(Document document,
                                                    TestAllStudentScoresVO testAllStudentScoreVO) throws Exception {
        if (CollectionUtils.isNotEmpty(testAllStudentScoreVO.getAllClassByVOList())) {
            //表头内容
            List<String> tableHeadList = Arrays.asList("姓名", "班级", "分数");
            //创建表格头并设置表格头部元素信息
            PdfPTable physicalSubstanceTable = createTableInfo(document, National_Excellent_Children, 3, tableHeadList);
            //填充表格其余元素信息
            nationalExcel(physicalSubstanceTable, testAllStudentScoreVO);
            document.add(physicalSubstanceTable);
        }
    }

    /**
     * 创建学生综合分析各测试项目成绩对比柱状图
     *
     * @param document 文档对象
     * @throws Exception 异常信息
     */
    private static void setClassComprehensiveTests(Document document, TestAllStudentScoresVO testAllStudentScoreVO) throws Exception {
        if (CollectionUtils.isNotEmpty(testAllStudentScoreVO.getAllStudentScoreVOList())) {
            // 获取班级名称 以班级名称分组排序
            Map<String, List<AllStudentScoreVO>> collect = testAllStudentScoreVO.getAllStudentScoreVOList()
                    .stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.groupingBy(AllStudentScoreVO::getClassType));
            // 获取班级类型集合
            List<String> classTypeList = new ArrayList<>();
            Collections.addAll(classTypeList, "LARGE_CLASS", "MIDDLE_CLASS", "SMALL_CLASS", "GRADUATE");
            for (String classType : classTypeList) {
                // 判断班级类型是否为空
                if (Objects.nonNull(collect.get(classType))) {
                    List<AllStudentScoreVO> allStudentScoreVOS = collect.get(classType);
                    if (classType.equals("LARGE_CLASS")) {
                        classType = "大班";
                    }
                    if (classType.equals("MIDDLE_CLASS")) {
                        classType = "中班";
                    }
                    if (classType.equals("SMALL_CLASS")) {
                        classType = "小班";
                    }
                    if (classType.equals("GRADUATE")) {
                        classType = "毕业";
                    }
                    if (allStudentScoreVOS.size() > 0) {
                        //x轴集合
                        List<String> xAxisNameList = new ArrayList<>();
                        //图例名称列表集合
                        List<String> legendNameList = new ArrayList<>();
                        // 数据集合
                        List<Object> dataList = new ArrayList<>();
                        //分数集合
                        List<BigDecimal> BigDecimal = new ArrayList<>();
                        BigDecimal maxScore = java.math.BigDecimal.ZERO;
                        for (AllStudentScoreVO allStudentScoreVO : allStudentScoreVOS) {
                            // 判断班级名字 以及 班级下边的分数 是否为空
                            if (StringUtils.isNotBlank(allStudentScoreVO.getClassName())) {
                                xAxisNameList.add(allStudentScoreVO.getClassName());
                                legendNameList.add(allStudentScoreVO.getClassName());
                                dataList.add(Objects.nonNull(allStudentScoreVO.getItemScoreAll()) ? allStudentScoreVO.getItemScoreAll() : new BigDecimal(0));
                                BigDecimal.add(Objects.nonNull(allStudentScoreVO.getItemScoreAll()) ? allStudentScoreVO.getItemScoreAll() : new BigDecimal(0));
                            }
                        }
                        // 获取最大分数
                        if (CollectionUtils.isNotEmpty(BigDecimal)) {
                            maxScore = Collections.max(BigDecimal);
                        }
                        //图例背景颜色
                        if (xAxisNameList.size() > 0 && dataList.size() > 0) {
                            List<Color> legendColorList = new ArrayList<>(Collections.singletonList(new Color(248, 99, 134)));
                            JFreeChart chart = GenerateBarChartUtil.createSimpleBarChart(classType, legendNameList, xAxisNameList
                                    , dataList, FreeChartUtil.createChartTheme("宋体"), "", "",
                                    0d, maxScore.doubleValue(), legendColorList, true, "{2}");
                            savePictureToDocument(document, chart, CLASS_COMPREHENSIVE_TEST_RESULTS);
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置幼儿园的基本信息
     *
     * @param document                   文本对象
     * @param kindergartenSideAnalysisVO 幼儿园数据
     * @return void
     **/
    private static void setKindergarten(Document document, KindergartenSideAnalysisVO kindergartenSideAnalysisVO) throws Exception {
        //二级标题
        if (Objects.nonNull(kindergartenSideAnalysisVO)) {
            Paragraph studentInfoTitleParagraph = createHeadInfo(PHYSICAL_ANALYSIS_HEAD);
            document.add(studentInfoTitleParagraph);
            //基本信息
            Font font = createFont(12, Font.NORMAL);
            String KindergartenName = StringUtils.isBlank(kindergartenSideAnalysisVO.getKindergartenName()) ? "" : kindergartenSideAnalysisVO.getKindergartenName();
            String KindergartenType = StringUtils.isBlank(kindergartenSideAnalysisVO.getKindergartenType()) ? "" : kindergartenSideAnalysisVO.getKindergartenType();
            Integer TestItemStudentCount = Objects.isNull(kindergartenSideAnalysisVO.getTestItemStudentCount()) ? null : kindergartenSideAnalysisVO.getTestItemStudentCount();
            if (KindergartenType.equals("public_handle")) {
                KindergartenType = "公办";
            } else {
                KindergartenType = "私有";
            }
            String info = "   幼儿园性质：" + KindergartenType + "          参与体侧人数：" + TestItemStudentCount + "人";
            Paragraph studentInfoParagraph = new Paragraph(info, font);
            studentInfoParagraph.setSpacingAfter(10);
            studentInfoParagraph.setSpacingBefore(10);
            studentInfoParagraph.setAlignment(Element.ALIGN_CENTER);
            document.add(studentInfoParagraph);
        }
    }


    /**
     * 填充表格内容
     *
     * @param table 表格对象
     */
    private static void nationalExcel(PdfPTable table, TestAllStudentScoresVO testAllStudentScoreVO) throws Exception {
        for (AllClassByVO scoreInfo : testAllStudentScoreVO.getAllClassByVOList()) {
            //设置表格内容的字体与内容
            table.addCell(createTableContent(StringUtils.isBlank(scoreInfo.getStudentName()) ? "" : scoreInfo.getStudentName()));
            table.addCell(createTableContent(StringUtils.isBlank(scoreInfo.getClassName()) ? "" : scoreInfo.getClassName()));
            //设置成绩
            table.addCell(createTableContent(Objects.isNull(scoreInfo.getItemFraction()) ? BigDecimal.ZERO.toString() : scoreInfo.getItemFraction().toString()));
        }
    }

    /**
     * 创建表格公共方法，包含创建表格所在文档段落，表格样式，表头以及表头内容设置
     *
     * @param document      文档对象
     * @param tableTitle    表格标题
     * @param numColumns    表格列数
     * @param tableHeadList 表头内容
     * @return table 表格对象
     * @throws Exception 异常信息
     */
    private static PdfPTable createTableInfo(Document document, String tableTitle, int numColumns, List<String> tableHeadList) throws Exception {
        Paragraph actionDevelopParagraph = createHeadThreeInfo(tableTitle);
        document.add(actionDevelopParagraph);
        //创建表格对象并设置样式
        PdfPTable table = new PdfPTable(numColumns);
        table.setTotalWidth(PageSize.A4.getWidth() - 100);
        table.setLockedWidth(true);
        //创建表头并塞值
        createTableHead(table, tableHeadList);
        return table;
    }

    /**
     * 根据传入的标题名称：批量设置标题值
     *
     * @param table         创建的表格对象
     * @param tableHeadList 每个标题值按顺序来
     */
    private static void createTableHead(PdfPTable table, List<String> tableHeadList) throws Exception {
        if (CollectionUtils.isEmpty(tableHeadList)) {
            return;
        }
        //获取设置表格标题的字体
        Font font = createFont(12, Font.NORMAL);
        for (String tableHeadTitle : tableHeadList) {
            PdfPCell pdfCell = new PdfPCell(new Phrase(tableHeadTitle, font));
            pdfCell.setBackgroundColor(new BaseColor(221, 221, 221));
            pdfCell.setMinimumHeight(20);
            pdfCell.setUseAscender(true);
            pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            table.addCell(pdfCell);
        }
    }

    /**
     * 填充身体素质分析表格内容
     *
     * @param table 表格对象
     */
    private static void nationalOutstandingChildren(PdfPTable table, TestAllStudentScoresVO testAllStudentScoreVO) throws Exception {

        for (TestAllStudentScoreVO scoreInfo : testAllStudentScoreVO.getTestAllStudentScoreVOList()) {
            //设置表格内容的字体与内容
            table.addCell(createTableContent(StringUtils.isBlank(scoreInfo.getStudentName()) ? "" : scoreInfo.getStudentName()));
            table.addCell(createTableContent(StringUtils.isBlank(scoreInfo.getClassName()) ? "" : scoreInfo.getClassName()));
            //设置成绩
            table.addCell(createTableContent(Objects.isNull(scoreInfo.getItemFraction()) ? BigDecimal.ZERO.toString() : scoreInfo.getItemFraction().toString()));

        }
    }

    /**
     * 创建空的段落名称
     *
     * @return 时间的段落
     */
    private static Paragraph createEmptyHeadInfo() throws Exception {
        Font font = createFont(14, Font.BOLD);
        Paragraph paragraph = new Paragraph("", font);
        paragraph.setSpacingAfter(150);
        paragraph.setSpacingBefore(150);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }

}
