#!/usr/bin/env python
# -*- coding:utf-8 -*-
from typing import Dict

import docx
import copy
import threading
import platform
import os
import clr  # add C# suppor
import gc
from datetime import datetime
from core.analysis_chart import *
from shutil import copyfile
from core.AnalysisMongoDetail import *
from pathlib import Path
from docx.shared import Cm
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml
from docx.shared import RGBColor #设置字体的颜色
from docx import Document
from docx.oxml.ns import qn
import xlwings as xw
from operator import *
import jpype
from jpype import *
import zipfile
import shutil
import requests
import urllib.parse
import sys
import subprocess
import chardet
from controllers.nacos_py import *


def myReportMain(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup, fileName, edition, updateFlag,
                 templateFileServerUrl,casesCondition):
    lock, fileCount = threading.Lock(), 0
    if str(os.path.abspath(os.curdir)).find("core") > 0:
        filePath = os.path.abspath(os.curdir).replace("core", "docx")
    else:
        filePath = os.path.join(os.path.abspath(os.curdir), "docx")
    fileZipPath = os.path.join(filePath, 'report', datetime.datetime.now().strftime('%Y%m%d%H%M%S%f'))
    isExists = os.path.exists(fileZipPath)
    if not isExists:
        os.makedirs(fileZipPath)

    for fileItem in fileGroup:
        if casesCondition is None:
            casesCondition = {caseFilter:fileItem}
        else:
            casesCondition[caseFilter] = fileItem
        fileCount += 1
        nowString,targetPath = datetime.datetime.now().strftime('%H%M%S%f'), None
        chartfile, report = str(TempID) + nowString + ".txt", myReportCreate()
        threadReport = threading.Thread(target=report.report,
                                        args=(PlatID, ProjID, TempID, mongodb_cfg, fileItem, fileName, chartfile,
                                              edition, updateFlag, casesCondition, ))
        threadChart = threading.Thread(target=report.chart, args=(chartfile, fileZipPath, lock,))
        threadReport.start()
        threadReport.join()
        threadChart.start()
        if fileCount == len(fileGroup):
            threadChart.join()

    returnFileZipPath = zipDir(fileZipPath)
    if ProjID == "1":
        os.remove(returnFileZipPath)
        return None
    else:
        shutil.rmtree(fileZipPath)
        return returnFileZipPath


def myReportDownJava(PlatID, ProjID, TempID, edition):
    template_file = ''
    template_fileCursor = mongo_template_file_select(PlatID, mongodb_cfg, ProjID, TempID)
    for template_fileCursorItem in template_fileCursor:
        template_file = template_fileCursorItem
    if isinstance(template_file, dict):
        templateFiles = template_file['templateFiles']
        for templateFilesIndex, templateFilesItem in enumerate(templateFiles):
            if str(templateFilesItem['edition']).strip() == edition.strip():
                templateFiles[templateFilesIndex]['reportPath'] = ''
        mongo_template_file_update(mongodb_cfg, TempID, dict(templateFiles=templateFiles))


def myReportMainJava(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup, fileName, edition, updateFlag,
                     templateFileServerUrl, casesCondition):
    fileCount, template_file = 0, ''
    if str(os.path.abspath(os.curdir)).find("core") > 0:
        filePath = os.path.abspath(os.curdir).replace("core", "docx")
    else:
        filePath = os.path.join(os.path.abspath(os.curdir), "docx")
    fileZipPath = os.path.join(filePath, 'report', datetime.datetime.now().strftime('%Y%m%d%H%M%S%f'))
    isExists = os.path.exists(fileZipPath)
    if not isExists:
        os.makedirs(fileZipPath)

    """
    template_fileCursor = mongo_template_file_select(PlatID, mongodb_cfg, ProjID, TempID)
    for template_fileCursorItem in template_fileCursor:
        template_file = template_fileCursorItem
    if str(os.path.abspath(os.curdir)).find("core") > 0:
        ext_classpath = os.path.join(os.path.abspath(os.curdir), 'ReportChartReplace-1.0-SNAPSHOT.jar')
    else:
        ext_classpath = os.path.join(os.path.abspath(os.curdir), 'core', 'ReportChartReplace-1.0-SNAPSHOT.jar')
    try:
        jvmPath = jpype.getDefaultJVMPath()  # 默认的JVM路径
        if not jpype.isJVMStarted():
            jpype.startJVM(jvmPath, "-ea", "-Djava.class.path=%s" % ext_classpath, '-Xss102400K')
    except Exception as ex:
        pass
    JDClass = JClass("com.zkey.Main")
        if isinstance(template_file, dict):
        templateFiles = template_file['templateFiles']
        for templateFilesIndex, templateFilesItem in enumerate(templateFiles):
            if str(templateFilesItem['edition']).strip() == edition.strip():
                templateFiles[templateFilesIndex]['reportPath'] = returnFileZipPath
        mongo_template_file_update(mongodb_cfg, TempID, dict(templateFiles=templateFiles))
    """
    if ProjID != "1":
        templateDownLoad(ProjID, TempID, edition, TokenID, templateFileServerUrl)      #模板下载
    #fileDle(os.path.join(filePath, 'report'))  #文件删除
    for fileItem in fileGroup:
        if casesCondition is None:
            casesCondition = {caseFilter:fileItem}
        else:
            casesCondition[caseFilter] = fileItem
        fileCount += 1
        nowString,targetPath = datetime.datetime.now().strftime('%H%M%S%f'), None
        chartfile, reportClass = str(TempID) + nowString + ".txt", myReportCreate()
        reportClass.report(PlatID, ProjID, TempID, mongodb_cfg, fileItem, fileName, chartfile, edition, updateFlag,
                           casesCondition)
        reportClass.javaChart(chartfile, fileZipPath)

    #if jpype.isJVMStarted():
    #    jpype.shutdownJVM()
    returnFileZipPath = zipDir(fileZipPath)
    shutil.rmtree(fileZipPath)
    return returnFileZipPath


class myReportCreate:
    def __init__(self):
        self._targetPath = None
        self._conditionReplace = None
        self._tableHead = None
        self._rowDelete = None
        self._replaceText = None
        self._replaceChart = None
        #self._JDClass = JDClass

    def report(self, PlatID, ProjID, TempID, mongodb_cfg, fileItem, fileName, chartfile, edition, updateFlag, Condition):
        wordflag, documentDocx, targetPath, filePath, templateError, NewFileName, fileCondition = \
            False, None, None, "", "相关模板未设定", "", ""

        try:
            if Condition and str(Condition).strip() != '':
                for key, value in Condition.items():
                    if value != fileItem:
                        fileCondition = fileCondition + value
            else:
                Condition = None
            templateData = mongo_template_logic(PlatID, mongodb_cfg, ProjID, TempID)
            # templateCount = mongo_template_logic(PlatID, ProjID, TempID)
            if templateData is not None:
                if str(os.path.abspath(os.curdir)).find("core") > 0:
                    filePath = os.path.abspath(os.curdir).replace("core", "docx")
                else:
                    filePath = os.path.join(os.path.abspath(os.curdir), "docx")
                sourcefile, nowString = TempID + edition + ".docx", datetime.datetime.now().strftime('%H%M%S%f')
                targetfile = str(TempID) + nowString + ".docx"
                sourcePath = os.path.join(filePath, 'template', sourcefile)
                targetPath = os.path.join(filePath, 'report', targetfile)
                my_file = Path(sourcePath)
                if my_file.is_file():
                    my_file = Path(targetPath)
                    if my_file.is_file():
                        os.unlink(targetPath)
                    copyfile(sourcePath, targetPath)
                    documentDocx, wordflag, templateError = docx.Document(targetPath), True, ""
                    for templateItem in templateData:
                        template = templateItem["template"]
                        for rowItem in template:
                            if rowItem["type"] == "title":
                                pass
                            elif rowItem["type"] == "paragraph":
                                pass
                            elif rowItem["type"] == "catalog":
                                pass
                            elif rowItem["type"] == "separator":
                                pass
                            elif rowItem["type"] == "text":
                                if "replace" in rowItem.keys():
                                    for replaceItem in rowItem["replace"]:
                                        replaceFlag = False
                                        for keyCondition, valueCondition in Condition.items():
                                            if valueCondition in replaceItem["condition"]:
                                                replaceFlag = True
                                                break
                                        if replaceFlag:
                                            self._replaceText = replaceItem["replace"]
                            elif rowItem["type"] == "table":
                                if "replace" in rowItem.keys():
                                    replace, cell, content, position, self._tableHead = \
                                        rowItem["replace"], [], [], [], {}
                                    for replaceItem in replace:
                                        replaceFlag = False
                                        for keyCondition, valueCondition in Condition.items():
                                            if valueCondition in replaceItem["condition"]:
                                                replaceFlag = True
                                                break
                                        if replaceFlag:
                                            cell.append(replaceItem["cell"])
                                            content.append(str(replaceItem["content"]).strip())
                                            if str(replaceItem["position"]).find("表") >= 0:
                                                position.append(str(replaceItem["position"]).strip())
                                            else:
                                                position.append("[表" + str(replaceItem["position"]).strip() + "]")
                                    if len(cell) > 0 :
                                        self._tableHead["cell"] = cell
                                        self._tableHead["content"] = content
                                        self._tableHead["position"] = position
                                    else:
                                        self._tableHead = None
                            elif rowItem["type"] == "condition":
                                json_data, json_data_flag = {}, True
                                if "analy" in rowItem.keys():
                                    analysis = rowItem["analy"]
                                    json_data, json_data_flag = \
                                        myAnalysis(PlatID, ProjID, mongodb_cfg, analysis, Condition, None, "", "")
                                if "content" in rowItem.keys():
                                    content, self._conditionReplace = rowItem["content"], []
                                    for contentRow in content:
                                        if contentRow["type"] == "replace":
                                            replaceFrom = contentRow["replaceFrom"]
                                            if str(contentRow["replaceTo"]).find("data") > -1 and \
                                                    str(contentRow["replaceTo"]).find(":") > -1:
                                                replaceToData = str(contentRow["replaceTo"]).split(':')
                                                datasource = json.loads(json_data[replaceToData[0]])
                                                datasource["detailValid"].sort(key=lambda x: x["validpercent"], reverse=True)
                                                if len(datasource["detailValid"]) > 0:
                                                    for keyWords, valueWords in replaceFrom.items():
                                                        if check_json_format(json.dumps(valueWords)):
                                                            for keyWordsItem, valueWordsItem in valueWords.items():
                                                                replaceFrom[keyWords] = {keyWordsItem :
                                                                        str(datasource["detailValid"][0][replaceToData[1]])}
                                                        else:
                                                            replaceFrom[keyWords] = \
                                                                str(datasource["detailValid"][0][replaceToData[1]])
                                            else:
                                                if "condition" in contentRow.keys():
                                                    for keyCondition, valueCondition in Condition.items():
                                                        if valueCondition in contentRow["condition"]:
                                                            for keyWords, valueWords in replaceFrom.items():
                                                                replaceFrom[keyWords] = str(contentRow["replaceTo"])
                                                else:
                                                    for keyWords, valueWords in replaceFrom.items():
                                                        replaceFrom[keyWords] = str(contentRow["replaceTo"])
                                            self._conditionReplace.append(replaceFrom)
                                        if contentRow["type"] == "fileReplace":
                                            fileReplace, fileReplaceName = str(contentRow["replace"]).split('&'), ""
                                            for fileReplaceItem in fileReplace:
                                                if str(fileReplaceItem).find("data") > -1 and \
                                                        str(fileReplaceItem).find(":") > -1:
                                                    replaceData = str(fileReplaceItem).split(':')
                                                    datasource = json.loads(json_data[replaceData[0]])
                                                    if len(datasource["detailValid"]) > 0:
                                                        fileReplaceName = \
                                                            fileReplaceName + \
                                                            str(datasource["detailValid"][0][replaceData[1]]).strip()
                                                else:
                                                    fileReplaceName = fileReplaceName + str(fileReplaceItem).strip()
                                            fileItem = fileReplaceName
                                        if contentRow["type"] == "chartReplace":
                                            chartReplace, fileReplaceName = str(contentRow["replace"]), ""
                                            for chartReplaceIndex, chartReplaceItem in enumerate(chartReplace[1]):
                                                if str(chartReplaceItem).find("data") > -1 and \
                                                        str(chartReplaceItem).find(":") > -1:
                                                    replaceData = str(chartReplaceItem).split(':')
                                                    datasource = json.loads(json_data[replaceData[0]])
                                                    if len(datasource["detailValid"]) > 0:
                                                        chartReplace[1][chartReplaceIndex] = \
                                                            str(datasource["detailValid"][0][replaceData[1]]).strip()
                                            self._replaceChart = chartReplace
                                if "rowDelete" in rowItem.keys():
                                    for keyCondition, valueCondition in Condition.items():
                                        if valueCondition in rowItem["rowDelete"]:
                                            self._rowDelete = True
                            elif rowItem["type"] == "analy":
                                analysis, content, json_data, json_data_flag = \
                                    rowItem["analy"], rowItem["content"], None, True
                                if myTemplateCheck(PlatID, ProjID, TempID, mongodb_cfg, analysis) or updateFlag:
                                    if updateFlag:
                                        mongo_analysis_report_delete(PlatID, mongodb_cfg, ProjID,  TempID,
                                                                     fileItem + fileCondition)
                                    else:
                                        json_data_mongo = mongo_analysis_select(PlatID, mongodb_cfg, ProjID, TempID,
                                                                                fileItem + fileCondition)
                                        for json_data_mongo_item in json_data_mongo:
                                            json_data = json_data_mongo_item["json_data"]
                                    if json_data is None:
                                        json_data, json_data_flag = myAnalysis(PlatID, ProjID, mongodb_cfg, analysis,
                                                                               Condition, self._conditionReplace,
                                                                               self._rowDelete, TempID)
                                        analysisJson = dict(platId=PlatID, projId=ProjID, tempId=TempID,
                                                            reportId=fileItem + fileCondition, json_data=json_data)
                                        if json_data and json_data_flag: mongo_analysis_insert(mongodb_cfg, analysisJson)
                                else:
                                    json_data, json_data_flag = myAnalysis(PlatID, ProjID, mongodb_cfg, analysis,
                                                                           Condition, self._conditionReplace,
                                                                           self._rowDelete, TempID)
                                    analysisJson = dict(platId=PlatID, projId=ProjID, tempId=TempID,
                                                        reportId=fileItem + fileCondition, json_data=json_data)
                                    if json_data and json_data_flag : mongo_analysis_insert(mongodb_cfg, analysisJson)
                                myTemplateUpdate(PlatID, ProjID, TempID, mongodb_cfg, template)
                                if json_data : myReport(documentDocx, content, json_data, chartfile, self._tableHead,
                                                        self._replaceText, self._replaceChart)
                else:
                    raise MyCustomError(retcode=6001)
        except Exception as ex:
            ex = FormatErrorCode(ex)
            my_log.error(ex)
        finally:
            if wordflag:
                if fileName.find("XXX") > -1:
                    NewFileName = fileName.replace("XXX", fileItem)
                else:
                    NewFileName = fileItem + fileName
                documentDocx.save(targetPath)
                if platform.system() == 'Windows':
                    tmp = os.popen("ps -af").read()
                    word_count = tmp.count('word')
                    if word_count > 0:
                        os.system("killall -9 word")
                if NewFileName and NewFileName.split() != "":
                    dirname, filename = os.path.split(targetPath)
                    filename, extension = os.path.splitext(filename)
                    extension = extension + templateError
                    new_targetPath = os.path.join(dirname, NewFileName + extension)
                    my_file = Path(new_targetPath)
                    if my_file.is_file():
                        new_targetPath = os.path.join(dirname, filename + NewFileName + extension)
                    os.rename(targetPath, new_targetPath)
                    targetPath = new_targetPath
        self._targetPath = targetPath
        try:
            for x in locals().keys():
                del locals()[x]
            gc.collect()
        except Exception as e:
            pass


    def chart(self, chartfile, fileZipPath, lock):
        lock.acquire()
        if str(os.path.abspath(os.curdir)).find("core") > 0:
            filePath = os.path.abspath(os.curdir).replace("core", "docx")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
        chartJsonPath = os.path.join(filePath, 'charts', chartfile)
        if platform.system() == 'Windows' and os.path.exists(chartJsonPath):
            try:
                clr.AddReference("WordChartHelper")
                # clr.FindAssembly('WordChartHelper')
                import WordChartHelper
                chart = WordChartHelper.WordChartHelper()
                chart.ChartCreate(chartJsonPath, self._targetPath)
            except Exception as ex:
                pass
            finally:
                os.remove(chartJsonPath)
                shutil.move(self._targetPath, fileZipPath)
        lock.release()
        try:
            for x in locals().keys():
                del locals()[x]
            gc.collect()
        except Exception as e:
            pass

    """
    def javaChart(self, chartfile, fileZipPath):
        chartJsonString = ""
        if str(os.path.abspath(os.curdir)).find("core") > 0:
            filePath = os.path.abspath(os.curdir).replace("core", "docx")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
        chartJsonPath = os.path.join(filePath, 'charts', chartfile)
        logFilePath = os.path.join(filePath, 'charts', datetime.datetime.now().strftime('%H%M%S%f') + '.txt')
        if os.path.exists(chartJsonPath) and self._JDClass is not None:
            try:
                with open(chartJsonPath, "r", encoding="utf-8") as f:
                    chartJsonString = json.load(f)
                    f.close()
                chartJsonString = json.dumps(chartJsonString)
                #jd = self._JDClass()
                self._JDClass.replaceChartData(self._targetPath, chartJsonString, logFilePath)
            except Exception as ex:
                pass
            finally:
                os.remove(chartJsonPath)
                shutil.move(self._targetPath, fileZipPath)
        else:
            shutil.move(self._targetPath, fileZipPath)
    """

    def javaChart(self, chartfile, fileZipPath):
        if str(os.path.abspath(os.curdir)).find("core") > 0:
            filePath = os.path.abspath(os.curdir).replace("core", "docx")
            chartPath = os.path.join(os.path.abspath(os.curdir), "ReportChartReplace-1.0-SNAPSHOT.jar")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
            chartPath = os.path.join(os.path.abspath(os.curdir), "core", "ReportChartReplace-1.0-SNAPSHOT.jar")
        chartJsonPath = os.path.join(filePath, 'charts', chartfile)
        logFilePath = os.path.join(filePath, 'charts', datetime.datetime.now().strftime('%H%M%S%f') + '.txt')
        if os.path.exists(chartJsonPath):
            try:
                command = "java -jar " + chartPath
                cmd = [command, self._targetPath, chartJsonPath, logFilePath]
                new_cmd = " ".join(cmd)
                print(new_cmd)
                stdout,stderr = subprocess.Popen(new_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE,
                                                 shell=True).communicate()
                #encoding = chardet.detect(stdout)["encoding"]
                #r = stdout.decode(encoding)
                print(stdout)
            except Exception as ex:
                print(ex)
                pass
            finally:
                os.remove(chartJsonPath)
                shutil.move(self._targetPath, fileZipPath)
        else:
            shutil.move(self._targetPath, fileZipPath)


def zipDir(dirPath):
    """
    压缩指定文件夹
    :param dirPath: 目标文件夹路径
    """
    outFullName = ""
    try:
        outFullName = dirPath + '.zip'
        zip = zipfile.ZipFile(outFullName,"w",zipfile.ZIP_DEFLATED)
        for path,dirNames,fileNames in os.walk(dirPath):
            for filename in fileNames:
                zip.write(os.path.join(path,filename), filename)
        zip.close()

    except Exception as ex:
        pass
    finally:
        return outFullName


def fileDle(dirPath):
    reportList = os.listdir(dirPath)
    for reportItem in reportList:
        f_path = os.path.join(dirPath, reportItem)
        if os.path.isdir(f_path):
            pass
        else:
            if str(f_path).find('.zip') < 0:os.remove(f_path)


def templateDownLoad(ProjID, tempID, templateEdition, tokenID, templateFileServerUrl):

    if str(os.path.abspath(os.curdir)).find("core") > 0:
        filePath = os.path.abspath(os.curdir).replace("core", "docx")
    else:
        filePath = os.path.join(os.path.abspath(os.curdir), "docx")
    targetfile = str(tempID) + templateEdition + ".docx"
    sourcePath = os.path.join(filePath, 'template', targetfile)
    my_file = Path(sourcePath)
    if my_file.is_file():
        os.remove(sourcePath)

    try:
        query = {"templateId": str(tempID), "edition": templateEdition}
        if templateFileServerUrl != "" :
            url = str(templateFileServerUrl).strip() + '/report/downloadReportTemplateWord'
        else:
            url = 'http://192.168.2.160:8851/report/downloadReportTemplateWord'
        url = url + '?' + urllib.parse.urlencode(query)
        #query = {"templateId": "627ba654a517907d77fdaf91", "edition": templateEdition}
        #url = 'https://medudata.bjmu.edu.cn/api/project/report/downloadReportTemplateWord/' + str(ProjID) + '?' + \
        #      urllib.parse.urlencode(query)
        print(url)
        if tokenID != "":
            headers = {'Authorization' : 'token = ' + tokenID}
            r = requests.post(url, headers = headers)
        else:
            r = requests.post(url)
        with open(sourcePath, "wb") as code:
            code.write(r.content)
        return True
    except Exception as ex:
        return False
    finally:
        pass


def caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow, noCondition, json_data, replaceCondition):
    case,keys,values,equalRange = None,[],[],""
    if "equalRange" in analysisRow.keys():
        equalRange = analysisRow["equalRange"]
    if Condition and noCondition == "":
        if "condition" in analysisRow and json.dumps(analysisRow["condition"]) != "":
            count,value = 0,""
            datasource = mongo_condition_logic(PlatID, mongodb_cfg, ProjID, analysisRow["dataSourceId"],
                                               str(analysisRow["condition"]).strip(),json.dumps(Condition))
            for rowItem in datasource:
                if float(rowItem['count'])>count:
                    value=str(rowItem['_id']).strip()
                    count=float(rowItem['count'])
            keys.append(str(analysisRow["condition"]).strip())
            values.append(value)
        else:
            if "filter" in analysisRow and isinstance(analysisRow["filter"], dict) and str(analysisRow["filter"]) != "":
                delKey = []
                for key, value in Condition.items():
                    for k, v in analysisRow["filter"].items():
                        if str(key) == str(k):
                            delKey.append(key)
                for caseItem in delKey:
                    Condition.pop(caseItem)
                if len(Condition) != 0:
                    for key, value in Condition.items():
                        keys.append(key)
                        values.append(value)
            else:
                case = Condition
    if "filter" in analysisRow and isinstance(analysisRow["filter"], dict) and str(analysisRow["filter"]) != "":
        for key, value in analysisRow["filter"].items():
            keys.append(key)
            if replaceCondition is not None:
                for replaceItem in replaceCondition:
                    for keyReplace, valueReplace in replaceItem.items():
                        if key == keyReplace:
                            if isinstance(value, str) and isinstance(valueReplace, str):
                                value = valueReplace
                            if isinstance(value, dict) and isinstance(valueReplace, dict):
                                value = valueReplace
            if isinstance(value, str) and str(value).find(':') > -1:
                dataFrom = str(value).strip().split(':')
                datasource = json.loads(json_data[dataFrom[0]])
                value = datasource["head"][0][dataFrom[1]]
            if check_json_format(json.dumps(value)):
                valueNew = {}
                for keyWords, valueWords in value.items():
                    if str(keyWords).strip() == "lte" or str(keyWords).strip() == "gte" or \
                            str(keyWords).strip() == "gt" or str(keyWords).strip() == "lt" or \
                            str(keyWords).strip() == "nin" or str(keyWords).strip() == "in" or \
                            str(keyWords).strip() == "regex" or str(keyWords).strip() == "ne":
                        if isinstance(valueWords, str) and str(valueWords).find(':') > -1:
                            dataFrom = str(valueWords).strip().split(':')
                            datasource = json.loads(json_data[dataFrom[0]])
                            valueWords = datasource["head"][0][dataFrom[1]]
                        if isinstance(equalRange, str) and str(equalRange) != "":
                            equalRangeData = str(equalRange).strip().split(':')
                            if is_number(valueWords) and valueWords - math.floor(valueWords) == 0 and \
                                    keyWords == equalRangeData[0]:
                                keyWords = equalRangeData[1]
                        keyWords = "$" + str(keyWords).strip()
                    valueNew[keyWords] = valueWords
                values.append(valueNew)
            else:
                values.append(value)
    if case is None:
        case = dict(zip(keys, values))
    return case


def worddiscription(documentWord, contentRow, json_data, discriptionJson, allReplace, textDiscription, tableDiscription,
                    tableIndexDiscription):
    """
    :param json_data:
    :param contentRow:
    :type documentWord: object
    """
    content = contentRow["content"]
    if "content" in content.keys(): contentFlag = True
    else: contentFlag = False
    text,fromtext,discriptionword,discriptionwordargs,bookMark,style = "", "", [],{},"",""
    pointdef = lambda :2 if "point" not in content.keys() else content["point"]
    pointGroupdef = lambda: "" if "pointGroup" not in content.keys() else str(content["pointGroup"])
    bookMarkdef = lambda: "" if "bookMark" not in content.keys() else content["bookMark"]
    styledef = lambda: "" if "style" not in content.keys() else content["style"]
    unitsdef = lambda :"" if "units" not in content.keys() else content["units"]
    countdef = lambda :1 if "count" not in content.keys() else int(content["count"])
    titledef = lambda: "" if "title" not in content.keys() else content["title"]
    datadef = lambda: None if "data" not in content.keys() else content["data"]
    rowTextdef = lambda: "" if "rowText" not in content.keys() else content["rowText"]
    sortFirstdef = lambda: [] if "sortFirst" not in content.keys() else content["sortFirst"]
    sortLastdef = lambda: [] if "sortLast" not in content.keys() else content["sortLast"]
    outColumndef = lambda: None if "outColumn" not in content.keys() else content["outColumn"]
    phrasedef = lambda: "" if "phrase" not in content.keys() else content["phrase"]
    wordHeaddef = lambda: "" if "wordHead" not in content.keys() else content["wordHead"]
    phraseDatadef = lambda: "" if "phraseData" not in content.keys() else content["phraseData"]
    replaceTextdef = lambda: "" if "replaceText" not in content.keys() else content["replaceText"]
    connectordef = lambda:"" if not contentFlag or "connector" not in content["content"].keys() \
        else content["content"]["connector"]
    point,units,countbreak,title, dataN, rowText, sortFirst, sortLast, outColumn, phrase, detailValid, columnMax, \
    connector, phraseData, wordHead, pointGroup, topStar, replaceText, equalFlag, bookMark, stylet = \
        pointdef(), unitsdef(), countdef(), titledef(), datadef(), rowTextdef(), sortFirstdef(), sortLastdef(), \
        outColumndef(), phrasedef(), [], 0, connectordef(), phraseDatadef(), wordHeaddef(), pointGroupdef(),\
        0, replaceTextdef(), False, bookMarkdef(), styledef()
    if title == '[SZYX_ZY]':
        testFlag = True
    if allReplace is not None:
        if isinstance(replaceText, str) and replaceText == "":
            replaceText = allReplace
        else:
            if isinstance(replaceText, list):
                for replace in allReplace[0]:
                    replaceText[0].append(replace)
                for replace in allReplace[1]:
                    replaceText[1].append(replace)
    if isinstance(point, str):point = int(point)
    if dataN is not None or outColumn is not None:
        if isinstance(dataN,list):
            if contentFlag and ("sort" in content["content"].keys() or "compare" in content["content"].keys()):
                datasource = dict(head=[],detailValid=[])
                phrase,analysis,count = content["phrase"],"",0
                for indexN, itemN in enumerate(dataN):
                    datafrom = json.loads(json_data[itemN])
                    if fromtext != "":
                        fromtext += "-"
                    fromtext += datafrom["head"][0]["variableID"]
                    analysis = datafrom["head"][0]["analysis"]
                    if datafrom["head"][0]["count"] != 0:
                        count += datafrom["head"][0]["count"]
                        if datafrom["head"][0]["analysis"] == "frequency":
                            num,per,groupAll = 0,0.0,content["group"]
                            for rowItem in datafrom["detailValid"]:
                                for ind,it in enumerate(groupAll):
                                    if float(str(rowItem["value"])) == float(str(it)):
                                        num+=int(rowItem["count"])
                                        if pointGroup == "":
                                            per += float(rowItem["validpercent"])
                                        else:
                                            per += float(str(formatdata(float(rowItem["validpercent"]),
                                                                        int(pointGroup) + 2)))
                            datasource["detailValid"].append(dict(value=str(indexN),text=phrase[indexN],
                                                                  count=num,validpercent=per))
                        elif datafrom["head"][0]["analysis"] == "means":
                            datasource['detailValid'].append(dict(valueRow=str(indexN),textRow=phrase[indexN],
                                                                  count=int(datafrom["head"][0]["count"]),
                                                                  average=float(datafrom["head"][0]["average"])))
                if title.strip() != "": fromtext = ""
                if analysis == "frequency":
                    datasource["head"].append(
                        dict(varLabel='', variableID=fromtext, count=count, analysis="frequency"))
                elif analysis == "means":
                    datasource["head"].append(
                        dict(rowVarLabel='', RowID=fromtext, ColumnID='', count=count, analysis="comparemeans"))
            else:
                datasource = json.loads(json_data[content["data"]])
        elif dataN is not None:
            datasource = json.loads(json_data[content["data"]])
        if outColumn is not None and isinstance(outColumn,list) and len(outColumn) > 0:
            datasource, count, detailRemove, columnStringBack = dict(head=[], detailValid=detailValid), 0, [], {}
            if len(sortFirst) != 0:
                rowNo, sortAll = -99999, sortFirst
            else:
                rowNo, sortAll = 99999, sortLast
            if rowText != "":
                detailValidTotal = rowDataProcess(outColumn, rowText, phrase, "", rowNo, sortAll, json_data, True,
                                                  phraseData, pointGroup)
                countFlag, countTotal, detailValidTotalIndex = False, [], 0
                if len(detailValidTotal) > 1:
                    for detailValidTotalItem in detailValidTotal:
                        if "count" in detailValidTotalItem[0]:
                            countFlag, countItem = True, 0
                            for detailItem in detailValidTotalItem:
                                countItem += detailItem["count"]
                            countTotal.append(countItem)
                        else:
                            countFlag = False
                if countFlag:
                    countCheck = 0
                    for countTotalIndex, countTotalItem in enumerate(countTotal):
                        if countCheck < countTotalItem:
                            countCheck, detailValidTotalIndex = countTotalItem, countTotalIndex
                detailValid = detailValidTotal[detailValidTotalIndex]
                for detailItem in detailValid:
                    if detailItem["columnMax"] > columnMax: columnMax = detailItem["columnMax"]
            else:
                for columnIndex in range(len(outColumn)):
                    detailValid.append(dict(value=int(columnIndex + 1)))
                    if isinstance(outColumn[columnIndex], list):
                        if len(outColumn[columnIndex]) > columnMax: columnMax = len(outColumn[columnIndex])
                        for indexCol in range(len(outColumn[columnIndex])):
                            detailValid = outDataProcess(outColumn[columnIndex][indexCol], indexCol, rowText, phrase,
                                                         json_data, detailValid,columnIndex,True,phraseData,pointGroup,
                                                         "", columnStringBack)
                    else:
                        if len(outColumn) > columnMax: columnMax = len(outColumn)
                        detailValid = outDataProcess(outColumn[columnIndex], columnIndex, rowText, phrase, json_data,
                                                     detailValid, -1, True, phraseData, pointGroup, "",columnStringBack)
            for detailIndex, detailItem in enumerate(detailValid):
                removeFlag, indexStar = True, 1
                if rowText != "" : indexStar = 0
                for indexColumn in range(indexStar, columnMax):
                    if (detailItem["column" + str(indexColumn)] is not None and
                            is_number(sort_key(detailItem["column" + str(indexColumn)], None)) and
                            float(str(sort_key(detailItem["column" + str(indexColumn)], None))) != 0.0) or \
                             (str(detailItem["columnName" + str(indexColumn)]).find("text") > -1 and
                              detailItem["column" + str(indexColumn)] is not None and
                              detailItem["column" + str(indexColumn)] != ""):
                        removeFlag = False
                    if detailItem["column" + str(indexColumn)] is None:
                        detailValid[detailIndex]["column" + str(indexColumn)] = 0
                if removeFlag:
                    detailRemove.append(detailItem)
            for detailItem in detailRemove:
                detailValid.remove(detailItem)
            datasource['detailValid'], count = detailValid, len(detailValid)
            datasource["head"].append(
                dict(varLabel='', variableID="", count=count, analysis="frequency"))
        head = datasource["head"][0]
        if head["count"] == 0 or (head["analysis"] != "means" and len(datasource["detailValid"]) == 0):
            if str(head["analysis"]) == "crosstabs" or str(head["analysis"]) == "comparemeans":
                if str(head["ColumnID"]).strip()=="":
                    fromtext = str(head["RowID"])
                else:
                    fromtext = str(head["RowID"]) + "-" + str(head["ColumnID"])
            elif head["analysis"] == "sort":
                if "variableID1" in head.keys():
                    fromtext = str(head["variableID1"]) + "-" + str(head["variableID2"]) + "-" + str(head["variableID3"])
                else:
                    fromtext = str(head["variableID"])
            else:
                fromtext = str(head["variableID"])
            if "outValue" in content.keys():
                fromtext += "-" + str(content["outValue"])
            text = "此题无相关数据！！！！！"
        else:
            if "outValue" in content.keys():
                if head["analysis"] == "wordcloud":
                    detailValid = datasource["detailValid"][0]
                    if len(detailValid) > 0:
                        if content["outValue"] == "count":
                            text = formatdata(float(str(detailValid[content["outValue"]])), 0)
                        elif content["outValue"] == "length":
                            text = str(len(detailValid))
                        else:
                            text = str(detailValid[content["outValue"]])
                else:
                    if content["outValue"] == "validP" or content["outValue"] == "invalidP"  or \
                            content["outValue"] == "passRate" or content["outValue"] == "masteryRate":
                        text = head[content["outValue"]] * 100
                    elif content["outValue"] == "count":
                        if head["analysis"] == "means":
                            text = head[content["outValue"]]
                        else:
                            text, detailValid = 0, datasource["detailValid"]
                            for detailValidItem in detailValid:
                                text += int(detailValidItem["count"])
                    elif content["outValue"] == "length":
                        detailValid = datasource["detailValid"]
                        text = str(len(detailValid))
                    else:
                        if content["outValue"] != "length":
                            text = head[content["outValue"]]
                if content["outValue"] == "validP" or content["outValue"] == "invalidP" or \
                    content["outValue"] == "average" or content["outValue"] == "median" or \
                    content["outValue"] == "stdev" or content["outValue"] == "variance" or \
                    content["outValue"] == "passRate" or content["outValue"] == "masteryRate" or \
                    content["outValue"] == "sum" or content["outValue"] == "max" or \
                    content["outValue"] == "min" or content["outValue"] == "mode":
                    text = str(formatdata(text, point))
                elif content["outValue"] == "count":
                    text = str(formatdata(text, 0))
                elif content["outValue"] == "length":
                    text = str(len(datasource["detailValid"]))
                else:
                    text = str(text)
                if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                    fromtext = str(head["RowID"]) + "-" + str(head["ColumnID"]) + "-" + str(content["outValue"])
                elif head["analysis"] == "sort":
                    if "variableID1" in head.keys():
                        fromtext = str(head["variableID1"])  + "-" + str(head["variableID2"]) + "-" \
                                   + str(head["variableID3"])  + "-" + content["outValue"]
                    else:
                        fromtext = str(head["variableID"]) + "-" + content["outValue"]
                else:
                    fromtext = str(head["variableID"]) + "-" + content["outValue"]
                text += units
                text = replacetext(text, replaceText)
            if contentFlag:
                text = content["content"]["discription"]
                if str(head["analysis"]) == "crosstabs":
                    detailValid, detailValidFrom, valueColumn, exception = [], datasource["detailValid"], [], []
                    if "exception" in content["content"].keys():
                        if isinstance(content["content"]["exception"], list):
                            exception = content["content"]["exception"]
                        else:
                            exception.append(content["content"]["exception"])
                    for detailValidItem in detailValidFrom:
                        if detailValidItem["textColumn"] not in valueColumn and \
                                detailValidItem["textColumn"] not in exception:
                            valueColumn.append(detailValidItem["textColumn"])
                    for valueItem in valueColumn:
                        percent, count, textRow, valueRow = 0, 0, "", 0
                        for detailValidItem in detailValidFrom:
                            if valueItem == detailValidItem["textColumn"] and detailValidItem["validpercent"] > percent:
                                percent, count = detailValidItem["validpercent"], detailValidItem["count"]
                                textRow, valueRow = detailValidItem["textRow"], detailValidItem["valueRow"]
                        detailValid.append(dict(valueRow=valueRow, textRow=textRow, textColumn=valueItem,
                                                validpercent=percent, count=count))
                else:
                    detailValid = datasource["detailValid"]
                if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                    if str(head["ColumnID"]).strip()=="":
                        fromtext = str(head["RowID"])
                    else:
                        fromtext = str(head["RowID"]) + "-" + str(head["ColumnID"])
                elif head["analysis"] == "sort":
                    if "variableID1" in head.keys():
                        fromtext = str(head["variableID1"]) + "-" + str(head["variableID2"]) + "-" + str(head["variableID3"])
                    else:
                        fromtext = str(head["variableID"])
                else:
                    fromtext = str(head["variableID"])
                if "sort" in content["content"].keys():
                    sortValue = "value"
                    if content["content"]["sort"] == "id" or content["content"]["sort"] == "-id":
                        if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                            sortValue = "valueRow"
                    if content["content"]["sort"] == "text" or content["content"]["sort"] == "-text":
                        if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                            sortValue = "textRow"
                        else:
                            sortValue = "text"
                    if content["content"]["sort"] == "per":
                        detailValid.sort(key=lambda x: x["validpercent"], reverse=False)
                    elif content["content"]["sort"] == "caseper":
                        detailValid.sort(key=lambda x: x["casepercent"], reverse=False)
                    elif content["content"]["sort"] == "-per":
                        detailValid.sort(key=lambda x: x["validpercent"], reverse=True)
                    elif content["content"]["sort"] == "-caseper":
                        detailValid.sort(key=lambda x: x["casepercent"], reverse=True)
                    elif content["content"]["sort"] == "count":
                        detailValid.sort(key=lambda x: x["count"], reverse=False)
                    elif content["content"]["sort"] == "-count":
                        detailValid.sort(key=lambda x: x["count"], reverse=True)
                    elif content["content"]["sort"] == "avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=False)
                    elif content["content"]["sort"] == "-avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=True)
                    elif content["content"]["sort"] == "textNum":
                        detailValid.sort(key=lambda x: sort_key(x["textColumn"], False), reverse=False)
                    elif content["content"]["sort"] == "-textNum":
                        detailValid.sort(key=lambda x: sort_key(x["textColumn"], True), reverse=True)
                    elif content["content"]["sort"] == "id" or content["content"]["sort"] == "text":
                        detailValid.sort(key=lambda x: x[sortValue], reverse=False)
                    elif content["content"]["sort"] == "-id" or content["content"]["sort"] == "-text":
                        detailValid.sort(key=lambda x: x[sortValue], reverse=True)
                    elif content["content"]["sort"] == "-pergroup" or content["content"]["sort"] == "pergroup":
                        detailValid = datasource["detailValidgroup"]
                        if content["content"]["sort"] == "-pergroup":
                            detailValid.sort(key=lambda x: x["validpercent"], reverse=True)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"], reverse=False)
                    if "count" in detailValid[0].keys():outColumn="count"
                    if "validpercent" in detailValid[0].keys(): outColumn = "validpercent"
                    if "casepercent" in detailValid[0].keys(): outColumn = "casepercent"
                    if "average" in detailValid[0].keys(): outColumn = "average"
                    if "outColumn" in content["content"].keys():
                        outColumn = content["content"]["outColumn"]
                    else:
                        if content["content"]["sort"] == "count" or content["content"]["sort"] == "-count":
                            outColumn = "count"
                        elif content["content"]["sort"] == "avg" or content["content"]["sort"] == "-avg":
                            outColumn = "average"
                        elif content["content"]["sort"] == "per" or content["content"]["sort"] == "-per":
                            outColumn = "validpercent"
                        elif content["content"]["sort"] == "caseper" or content["content"]["sort"] == "-caseper":
                            outColumn = "casepercent"
                        elif content["content"]["sort"] == "textNum" or content["content"]["sort"] == "-textNum":
                            outColumn = "textColumn"
                    if outColumn == 'validpercent' or outColumn == 'casepercent' or outColumn == 'average' or\
                            outColumn == 'count':
                        itemCount = ''
                        for detailValidItem in detailValid[0].keys():
                            if detailValidItem.find(outColumn) > -1 and detailValidItem != 'orderAverage':
                                itemCount = detailValidItem.replace(outColumn, '')
                        if itemCount != '':
                            for detailValidIndex in range(len(detailValid)):
                                detailValid[detailValidIndex]['orderAverage'] = len(detailValid) - detailValidIndex
                            for itemCountIndex in range(1, int(itemCount)):
                                detailValid.sort(key=lambda x: x[outColumn + str(itemCountIndex)], reverse=True)
                                for detailValidIndex in range(len(detailValid)):
                                    detailValid[detailValidIndex]['orderAverage'] = \
                                        detailValid[detailValidIndex]['orderAverage'] + \
                                        (len(detailValid) - detailValidIndex)
                            detailValid.sort(key=lambda x: x['orderAverage'], reverse=True)
                    if "exception" in content["content"].keys():
                        deletenum = []
                        for num in range(0, len(detailValid)):
                            if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                                optionname = detailValid[num]["textRow"]
                            else:
                                if "optiontext" in detailValid[num].keys():
                                    optionname = detailValid[num]["optiontext"]
                                else:
                                    optionname = detailValid[num]["text"]
                            if isinstance(content["content"]["exception"], list):
                                for exceptionItem in content["content"]["exception"]:
                                    if str(optionname).strip() == str(exceptionItem).strip():
                                        deletenum.append(num)
                                        break
                            else:
                                if str(optionname).strip() == str(content["content"]["exception"]).strip():
                                    deletenum.append(num)
                        if len(deletenum) > 0:
                            for deletenumItem in reversed(deletenum):
                                del detailValid[deletenumItem]
                    top,topValue,totalPer,totalNum,firstFlag,textRow,textColumn, topReplace, topReplaceIndex= \
                        len(detailValid), 0, 0.0, 0, False, "", "", -1, 0
                    if isinstance(replaceText, list):
                        for replaceIndex, replaceItem in enumerate(replaceText[0]):
                            if isinstance(replaceItem, dict) and "top" in replaceItem.keys():
                                topReplace,topReplaceIndex = replaceItem["top"], replaceIndex
                                if str(topReplace).strip().find("%") < 0:
                                    topReplace = returncount(detailValid, int(topReplace), outColumn, point)
                                break
                    if "top" in content["content"].keys():
                        if isinstance(content["content"]["top"], list):
                            top = int(content["content"]["top"][0])
                            if len(content["content"]["top"]) > 1 and \
                                str(content["content"]["top"][1]).strip() == "False":
                                top = returncountRepeat(detailValid, int(top), outColumn, point)
                            else:
                                topValue = top
                                if  not (isinstance(content["content"]["text"], str) and
                                         str(content["content"]["text"]).find("name") < 0 and top == 1):
                                    top = returncount(detailValid, int(top), outColumn, point)
                        else:
                            if str(content["content"]["top"]).strip().find("%") > -1 and \
                                    (outColumn == "casepercent" or outColumn == "validpercent"):
                                top, maxValue, maxValueReplace = \
                                    0, float(str(content["content"]["top"]).strip().replace("%", "")), 0
                                if str(topReplace).strip().find("%") > -1:
                                    maxValueReplace = float(str(topReplace).strip().replace("%", ""))
                                    topReplace = 0
                                for detailValidItem in detailValid:
                                    if float(str(formatdata(detailValidItem[outColumn] * 100, point))) >= maxValue:
                                        top += 1
                                    if topReplace != -1 and \
                                            float(str(formatdata(detailValidItem[outColumn] * 100, point)))\
                                            >= maxValueReplace:
                                        topReplace += 1
                            else:
                                top = int(content["content"]["top"])
                                topValue = top
                                if not (isinstance(content["content"]["text"], str) and
                                        str(content["content"]["text"]).find("name") < 0 and top == 1):
                                    top = returncount(detailValid, int(top), outColumn, point)
                    if "topStar" in content["content"].keys(): topStar = int(content["content"]["topStar"])
                    num_dict = ['零', '一', '两', '三', '四', '五', '六', '七', '八','九']
                    if topStar < top and len(detailValid) > 0:
                        equalFlag = True
                        for topNum in range(topStar, top):
                            if topNum > 0:
                                if outColumn == "validpercent" or outColumn == "casepercent":
                                    if float(str(formatdata(sort_key(str(detailValid[0][outColumn]), None) * 100, point))) != \
                                        float(str(formatdata(sort_key(str(detailValid[topNum][outColumn]), None) * 100, point))):
                                        equalFlag = False
                                else:
                                    if not float(str(formatdata(sort_key(str(detailValid[0][outColumn]), None), point))) == \
                                           float(str(formatdata(sort_key(str(detailValid[topNum][outColumn]), None), point))):
                                        equalFlag = False
                            else:
                                if top == 1 : equalFlag = False
                            if (outColumn == "validpercent" or outColumn == "casepercent") and \
                                    detailValid[topNum][outColumn] is not None:
                                totalPer += detailValid[topNum][outColumn]
                            if "count" in detailValid[topNum].keys() and detailValid[topNum]["count"] is not None:
                                totalNum += detailValid[topNum]["count"]
                    discriptionwordargs["totalPer"] = formatdata(totalPer * 100, point) + units
                    discriptionwordargs["totalNum"] = formatdata(totalNum, 0)
                    if len(detailValid) > 0:
                        discriptionwordargs["per"] = \
                            formatdata(sort_key(str(detailValid[0][outColumn]), None) * 100, point) + units
                        discriptionwordargs["avg"] = \
                            formatdata(sort_key(str(detailValid[0][outColumn]), None), point)
                    if top > 0 and topStar < top:
                        if topStar > 0 and topStar + 5 < top:top = topStar + 5
                        for num in range(topStar, top):
                            if head["analysis"] == "crosstabs":
                                if isinstance(detailValid[num]["textColumn"], list):
                                    optionname = ""
                                    for textItem in detailValid[num]["textColumn"]:
                                        optionname += str(textItem).strip()
                                else:
                                    optionname = detailValid[num]["textColumn"]
                                if isinstance(detailValid[num]["textRow"], list):
                                    textRow = ""
                                    for textItem in detailValid[num]["textRow"]:
                                        textRow += str(textItem).strip()
                                else:
                                    textRow = detailValid[num]["textRow"]
                                optionId = str(detailValid[num]["valueRow"])
                            elif head["analysis"] == "comparemeans":
                                if isinstance(detailValid[num]["textRow"], list):
                                    optionname = ""
                                    for textItem in detailValid[num]["textRow"]:
                                        optionname += str(textItem).strip()
                                else:
                                    optionname = detailValid[num]["textRow"]
                                optionId = str(detailValid[num]["valueRow"])
                            else:
                                if "optiontext" in detailValid[num].keys():
                                    optionname = detailValid[num]["optiontext"]
                                else:
                                    if isinstance(detailValid[num]["text"], list):
                                        optionname = ""
                                        for textItem in detailValid[num]["text"]:
                                            optionname += str(textItem).strip()
                                    else:
                                        optionname = detailValid[num]["text"]
                                optionId = str(detailValid[num]["value"])
                            percent,casepercent,average,passRate,masteryRate,percentileRank,count = "","","","","","",0
                            if "validpercent" in detailValid[0].keys():
                                percent = str(formatdata(sort_key(detailValid[num]["validpercent"], None) * 100, point)) + units
                            if "casepercent" in detailValid[0].keys():
                                casepercent = str(formatdata(sort_key(detailValid[num]["casepercent"], None) * 100, point)) + units
                            if "passRate" in detailValid[0].keys():
                                passRate = str(formatdata(detailValid[num]["passRate"] * 100, point)) + units
                            if "masteryRate" in detailValid[0].keys():
                                masteryRate = str(formatdata(detailValid[num]["masteryRate"] * 100, point)) + units
                            if "percentileRank" in detailValid[0].keys():
                                percentileRank = str(formatdata(detailValid[num]["percentileRank"] * 100, point)) + units
                            if "average" in detailValid[0].keys():
                                average = str(formatdata(sort_key(detailValid[num]["average"], None), point))
                            if "textColumn" in detailValid[0].keys():
                                textColumn = str(detailValid[num]["textColumn"])
                            if "count" in detailValid[num].keys():count = int(str(detailValid[num]["count"]).split('.')[0])
                            if optionId in content["content"].keys():
                                discriptionword.append(content["content"][optionId]. \
                                                       format(per=percent, caseper=casepercent, avg=average,
                                                              passRate=passRate, masteryRate=masteryRate,
                                                              percentileRank=percentileRank,count=count,
                                                              name=optionname, nameRow=textRow, nameColumn=textColumn))
                            elif "textall" in content["content"].keys():
                                valueIndex = "value"
                                if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                                    valueIndex = "valueRow"
                                for itemIndex,itemText in enumerate(content["content"]["textall"]):
                                    textFlag = False
                                    if "text" in content["content"].keys() and \
                                            isinstance(content["content"]["text"], list):
                                        if str(content["content"]["text"][itemIndex]).strip() == \
                                                str(detailValid[num][valueIndex]).strip():
                                            textFlag = True
                                    else:
                                        if float(itemIndex + 1) == float(detailValid[num][valueIndex]):
                                            textFlag = True
                                    if textFlag:
                                        if "text2" in content["content"].keys() and firstFlag == False:
                                            discriptionword.append(content["content"]["text2"].\
                                                                   format(per=percent, caseper=casepercent,
                                                                          passRate=passRate,masteryRate=masteryRate,
                                                                          percentileRank=percentileRank,avg=average,
                                                                          count=count, name=optionname, nameRow=textRow,
                                                                          nameColumn=textColumn))
                                            firstFlag = True
                                        else:
                                            discriptionword.append(itemText.
                                                                   format(per=percent, caseper=casepercent,
                                                                          passRate=passRate, masteryRate=masteryRate,
                                                                          percentileRank=percentileRank, avg=average,
                                                                          count=count, name=optionname, nameRow=textRow,
                                                                          nameColumn=textColumn))
                            else:
                                if "text2" in content["content"].keys() and len(discriptionword) == 0:
                                    contentText = content["content"]["text2"]
                                else:
                                    if isinstance(content["content"]["text"], list) and len(content["content"]["text"]) > 0:
                                        if not equalFlag or len(content["content"]["text"]) == 1:
                                            contentText = content["content"]["text"][0]
                                        else:
                                            contentText = content["content"]["text"][1]
                                    else:
                                        contentText = content["content"]["text"]
                                if top > topValue and equalFlag and num > 0 and isinstance(text, list):
                                    break
                                discriptionword.append(contentText. \
                                                       format(per=percent, caseper=casepercent, avg=average,
                                                              passRate=passRate, masteryRate=masteryRate,
                                                              percentileRank=percentileRank, count=count,
                                                              name=optionname, nameRow=textRow, nameColumn=textColumn))
                    discriptionwordargs["textColumn"] = textColumn
                    if (isinstance(connector, str) and connector != "") or isinstance(connector, list):
                        if isinstance(connector, str) and connector != "":
                            connector = [connector]
                        if isinstance(connector, list) and len(connector) == 1: connector.append(connector[0])
                        discriptionwordNew = ""
                        for discriptionItem in discriptionword:
                            if discriptionItem.find('、') > -1:
                                if not(discriptionItem.find('（') < discriptionItem.find('、') < discriptionItem.find('）')):
                                    if isinstance(connector, list):
                                        for connectorIndex in range(len(connector)):
                                            connector[connectorIndex] = connector[connectorIndex].replace("、", "，")
                                    break
                        for discriptionIndex, discriptionItem in enumerate(discriptionword):
                            if discriptionwordNew != "" and discriptionItem != "":
                                if isinstance(connector, str) and connector != "":
                                    discriptionwordNew += connector
                                else:
                                    if discriptionIndex == len(discriptionword) - 1:
                                        discriptionwordNew += connector[1]
                                    else:
                                        discriptionwordNew += connector[0]
                            if discriptionIndex < topReplace + 1:
                                replaceText[0][topReplaceIndex] = discriptionwordNew
                            discriptionwordNew += discriptionItem
                        discriptionword = [discriptionwordNew]
                    if isinstance(text, list) and len(text) > 0:
                        if equalFlag and len(text) >= 2:
                            if top > topValue and len(text) >= 3:
                                text = text[2]
                            else:
                                text = text[1]
                        elif equalFlag and len(text) == 2:
                            text = text[1]
                        elif top == 1 and len(text) == 4:
                            text = text[3]
                        else:
                            text = text[0]
                    if text.count('{}') > 1:
                        if top > text.count('{}'):top = text.count('{}')
                    if 0 < topStar < top:
                        discriptionwordargs["top"] = str(top - topStar)
                    else:
                        if top < 4:
                            discriptionwordargs["top"] = num_dict[top]
                        else:
                            discriptionwordargs["top"] = str(top)
                    if len(discriptionword) < 20:
                        for discriptionIndex in range(20 - len(discriptionword)):
                            discriptionword.append("")
                    if topStar < top:
                        if topReplace != -1 and discriptionword[1] != '':
                            for topReplaceIndex in range(topReplace):
                                del discriptionword[topReplaceIndex]
                        if len(discriptionwordargs) > 0:
                            text = text.format(*discriptionword, **discriptionwordargs)
                        else:
                            text = text.format(*discriptionword)
                        if topStar > 0 and topStar + 1 == top:
                            text = ""
                    else:
                        text = ""
                    if "phrase" in content["content"].keys():
                        phrase = content["content"]["phrase"]
                        outValue = str(phrase).split(':')
                        datasourceOut = json.loads(json_data[outValue[0]])
                        outValueText = str(datasourceOut["detailValid"][0][outValue[1]]).strip()
                        for detailValidIndex, detailValidItem in enumerate(detailValid):
                            if outValueText == str(detailValidItem["text"]).strip() or outValueText == \
                                    str(detailValidItem["value"]).strip() + str(detailValidItem["text"]).strip():
                                text = str(detailValidIndex + 1)
                                break
                    text = replacetext(text, replaceText)
                    if top == 0 and text != "":
                        text = text[-1]
                elif "compare" in content["content"].keys():
                    if "sortArray" in content["content"].keys():
                        if rowText != "": sortKey = 0
                        else:sortKey = 1
                        detailValid.sort(key=lambda x: x["column" + str(sortKey)], reverse=False)
                        sortArray = content["content"]["sortArray"]
                        compare, arrayText = content["content"]["compare"], ""
                        for sortIndex, sortItem in enumerate(sortArray):
                            equalFlag = False
                            for arrayIndex, arrayItem in sortItem:
                                if str(arrayItem).strip() != "" and arrayIndex < len(detailValid) and \
                                    str(arrayItem).strip() == str(detailValid[arrayIndex]["value"]).strip():
                                    equalFlag = True
                            if equalFlag and sortIndex < len(compare):
                                arrayText = compare[sortIndex]
                        percent, value, num, option, percentCompare, valueCompare, numCompare, equalFlag = \
                            [], [], [], [], 0, 0, 0, False
                        percentFrom, valueFrom, numFrom, percentTo, valueTo, numTo = "", "", "", "", "", ""
                        for detailValidIndex, detailValidItem in enumerate(detailValid):
                            percent.append(formatdata(float(detailValidItem[sortKey]) * 100, point))
                            value.append(formatdata(float(detailValidItem[sortKey]), point))
                            num.append(formatdata(float(detailValidItem[sortKey]), 0))
                            option.append(str(detailValidItem["text"]).strip())
                            if detailValidIndex == 0:
                                percentCompare = float(detailValidItem[sortKey]) * 100
                                valueCompare = float(detailValidItem[sortKey])
                                numCompare = float(detailValidItem[sortKey])
                            if detailValidIndex == len(detailValid) - 1:
                                percentCompare = formatdata(float(detailValidItem[sortKey]) * 100 - percentCompare, point)
                                valueCompare = formatdata(float(detailValidItem[sortKey]) - valueCompare, point)
                                numCompare = formatdata(float(detailValidItem[sortKey]) - numCompare, 0)
                        if len(percent) > 0 and len(value) > 0 and len(num) > 0:
                            percentFrom, valueFrom, numFrom = percent[0], value[0], num[0]
                            percentTo, valueTo, numTo = percent[len(percent) - 1], value[len(value) - 1], num[len(num) - 1]
                        if len(compare) > len(sortArray):
                            if percentCompare < 2.0 or valueCompare < 1.0:
                                arrayText = compare[len(sortArray)]
                        if len(compare) > len(sortArray) + 1:
                            if float(str(formatdata(percentCompare, point))) == 0.0 or \
                                    float(str(formatdata(valueCompare, point))) == 0.0:
                                arrayText = compare[len(sortArray) + 1]
                        discriptionword.append(content["content"]["text"].
                                               format(text=arrayText, percentCompare=percentCompare,
                                                      valueCompare=valueCompare, numCompare=numCompare, percent=percent,
                                                      value=value, count=num, option=option, percentFrom=percentFrom,
                                                      valueFrom=valueFrom, numFrom=numFrom, percentTo=percentTo,
                                                      valueTo=valueTo, numTo=numTo))
                    elif "group" in content.keys() or "group" in content["content"].keys():
                        if "group" in content.keys():
                            compareGroup = content["group"]
                        else:
                            compareGroup = content["content"]["group"]
                        if "text2" in content["content"].keys() and \
                                str(content["content"]["text2"]).strip() != "":
                            if "count" in detailValid[0].keys(): outColumn = "count"
                            if "validpercent" in detailValid[0].keys(): outColumn = "validpercent"
                            if "casepercent" in detailValid[0].keys(): outColumn = "casepercent"
                            if "average" in detailValid[0].keys(): outColumn = "average"
                            detailValid.sort(key=lambda x: x[outColumn], reverse=True)
                        for groupIndex, groupItem in enumerate(compareGroup[0]):
                            detailText, nameStr, connectorText, count, validpercent, average, casepercent = \
                                [], "", "", [], [], [], []
                            for dataItem in detailValid:
                                if compareReturn(compareGroup[1][groupIndex], groupItem,
                                                 compareGroup[2][groupIndex], dataItem):
                                    if "text" in dataItem.keys():
                                        detailText.append(str(dataItem["text"]).strip())
                                    elif "textRow" in dataItem.keys():
                                        detailText.append(str(dataItem["textRow"]).strip())
                                    else:
                                        detailText.append('')
                                    if "count" in dataItem.keys():
                                        count.append(str(formatdata(dataItem["count"] * 100, 0)))
                                    else:
                                        count.append('')
                                    if "validpercent" in dataItem.keys():
                                        validpercent.append(str(formatdata(dataItem["validpercent"] * 100, point)))
                                    else:
                                        validpercent.append('')
                                    if "casepercent" in dataItem.keys():
                                        casepercent.append(str(formatdata(dataItem["casepercent"] * 100, point)))
                                    else:
                                        casepercent.append('')
                                    if "average" in dataItem.keys():
                                        average.append(str(formatdata(dataItem["average"], point)))
                                    else:
                                        average.append('')
                            if len(detailText) > 0:
                                for textIndex, textItem in enumerate(detailText):
                                    if nameStr != "":
                                        if isinstance(connector, str):
                                            if connector != "" : nameStr += connector
                                        else:
                                            if len(connector) == 1: connector.append(connector[0])
                                            if textIndex == len(detailText) - 1:
                                                nameStr += connector[1]
                                            else:
                                                nameStr += connector[0]
                                    nameStr += textItem
                                if isinstance(content["content"]["compare"], list):
                                    if groupIndex < len(content["content"]["compare"]):
                                        connectorText = content["content"]["compare"][groupIndex]
                                    else:
                                        connectorText = content["content"]["compare"][0]
                                if isinstance(content["content"]["compare"], str):
                                    connectorText = str(content["content"]["compare"])
                                discriptionTextCompare, discriptionTextCompare2, discriptionText, discriptionText2 = \
                                    "", "", "", ""
                                if isinstance(content["content"]["text"], str):
                                    if str(content["content"]["text"]).find('compare') > -1:
                                        discriptionTextCompare = str(content["content"]["text"])
                                    else:
                                        discriptionText = str(content["content"]["text"])
                                    if "text2" in content["content"].keys() and \
                                        str(content["content"]["text2"]).strip() != "":
                                        discriptionWordString = ""
                                        if str(content["content"]["text2"]).find('compare') > -1:
                                            discriptionTextCompare2 = str(content["content"]["text2"])
                                        else:
                                            discriptionText2 = str(content["content"]["text2"])
                                        if discriptionText !=  "" or discriptionText2 != "":
                                            for detailTextIndex, detailTextItem in enumerate(detailText):
                                                discriptionWordString = discriptionWordString + \
                                                                        (discriptionText + discriptionText2).format(
                                                                            name=detailTextItem,
                                                                            per=validpercent[detailTextIndex],
                                                                            caseper=casepercent[detailTextIndex],
                                                                            avg=average[detailTextIndex],
                                                                            compare=connectorText)
                                        if discriptionTextCompare != "" or discriptionTextCompare2 != "":
                                            discriptionword.append(discriptionWordString + \
                                                                   (discriptionTextCompare + discriptionTextCompare2).
                                                                    format(name=nameStr, compare=connectorText))
                                if isinstance(content["content"]["text"], list):
                                    if groupIndex < len(content["content"]["text"]):
                                        discriptionword.append(content["content"]["text"][groupIndex].
                                                               format(name=nameStr, compare=connectorText))
                                    else:
                                        discriptionword.append(content["content"]["text"][0].
                                                               format(name=nameStr, compare=connectorText))
                    else:
                        if head["analysis"] == "crosstabs":
                            if len(datasource["detailValidgroup"]) > 0:
                                detailValid = datasource["detailValidgroup"]
                            else:
                                detailValid = datasource["detailValid"]
                        compare = content["content"]["compare"]
                        value1,count1,option1,value2,count2,option2 = 0,0,"",0,0,""
                        if head["analysis"] == "frequency" or head["analysis"] == "multiple":
                            if isinstance(compare[0], list):
                                value1,count1,option1,value2,count2,option2 = [],[],[],[],[],[]
                                for groupInd, compareGroup in enumerate(compare):
                                    for dataItem in detailValid:
                                        if str(compareGroup[0]).strip() == str(dataItem["value"]).strip() or \
                                                str(compareGroup[0]).strip() == str(dataItem["text"]).strip():
                                            if "validpercent" in dataItem.keys():
                                                value1.append(formatdata(float(dataItem["validpercent"]) * 100, point))
                                            if "casepercent" in dataItem.keys():
                                                value1.append(formatdata(float(dataItem["casepercent"]) * 100, point))
                                            if "textmax" in dataItem.keys():
                                                value1.append(float(sort_key(str(dataItem["textmax"]), None)))
                                            if "count" in dataItem.keys():
                                                count1.append(int(dataItem["count"]))
                                            else:
                                                if "column1" in dataItem.keys():
                                                    count1.append(int(sort_key(dataItem["column1"], None)))
                                            option1.append(dataItem["text"])
                                        elif str(compareGroup[1]).strip() == str(dataItem["value"]).strip() or \
                                                str(compareGroup[1]).strip() == str(dataItem["text"]).strip():
                                            if "validpercent" in dataItem.keys():
                                                value2.append(formatdata(float(dataItem["validpercent"]) * 100, point))
                                            if "textmax" in dataItem.keys():
                                                value2.append(float(sort_key(str(dataItem["textmax"]), None)))
                                            if "casepercent" in dataItem.keys():
                                                value2.append(formatdata(float(dataItem["casepercent"]) * 100, point))
                                            if "count" in dataItem.keys():
                                                count2.append(int(dataItem["count"]))
                                            else:
                                                if "column1" in dataItem.keys():
                                                    count2.append(int(sort_key(dataItem["column1"], None)))
                                            option2.append(dataItem["text"])
                                    if len(value1) == groupInd: value1.append(0), count1.append(0), option1.append("")
                                    if len(value2) == groupInd: value2.append(0), count2.append(0), option2.append("")
                            else:
                                for dataItem in detailValid:
                                    if str(compare[0]).strip() == str(dataItem["value"]).strip() or \
                                            str(compare[0]).strip() == str(dataItem["text"]).strip():
                                        if "count" in dataItem.keys():
                                            value1 = int(dataItem["count"])
                                        if "validpercent" in dataItem.keys():
                                            value1 = formatdata(float(dataItem["validpercent"]) * 100, point)
                                        if "casepercent" in dataItem.keys():
                                            value1 = formatdata(float(dataItem["casepercent"]) * 100, point)
                                        if "average" in dataItem.keys():
                                            value1 = formatdata(float(dataItem["average"]), point)
                                        if "textmax" in dataItem.keys():
                                            value1 = float(sort_key(str(dataItem["textmax"]), None))
                                        if "count" in dataItem.keys():
                                            count1 = int(dataItem["count"])
                                        else:
                                            if "column1" in dataItem.keys():
                                                count1 = int(sort_key(dataItem["column1"], None))
                                        option1 = dataItem["text"]
                                    elif str(compare[1]).strip() == str(dataItem["value"]).strip() or \
                                            str(compare[1]).strip() == str(dataItem["text"]).strip():
                                        if "count" in dataItem.keys():
                                            value2 = int(dataItem["count"])
                                        if "validpercent" in dataItem.keys():
                                            value2 = formatdata(float(dataItem["validpercent"]) * 100, point)
                                        if "casepercent" in dataItem.keys():
                                            value2 = formatdata(float(dataItem["validpercent"]) * 100, point)
                                        if "average" in dataItem.keys():
                                            value2 = formatdata(float(dataItem["average"]), point)
                                        if "textmax" in dataItem.keys():
                                            value2 = float(sort_key(str(dataItem["textmax"]), None))
                                        if "count" in dataItem.keys():
                                            count2 = int(dataItem["count"])
                                        else:
                                            if "column1" in dataItem.keys():
                                                count2 = int(sort_key(dataItem["column1"], None))
                                        option2 = dataItem["text"]
                        elif head["analysis"] == "crosstabs" and len(compare) > 1 and isinstance(compare[0], list) and \
                                isinstance(compare[1], list):
                            for dataItem in detailValid:
                                if str(compare[0][0]) == str(dataItem["valueRow"]) and \
                                        str(dataItem["valueColumn"]) in compare[1]:
                                    value1 += float(dataItem["validpercent"])
                                    count1 += int(dataItem["count"])
                                    option1 = dataItem["textRow"]
                                elif str(compare[0][1]) == str(dataItem["valueRow"]) and \
                                        str(dataItem["valueColumn"]) in compare[1]:
                                        value2 += float(dataItem["validpercent"])
                                        count2 += int(dataItem["count"])
                                        option2 = dataItem["textRow"]
                            value1 = formatdata(value1 * 100, point)
                            value2 = formatdata(value2 * 100, point)
                        elif head["analysis"] == "comparemeans":
                            for dataItem in detailValid:
                                if str(compare[0]) == str(dataItem["valueRow"]):
                                    value1 = formatdata(float(dataItem["average"]), point)
                                    count1 = int(dataItem["count"])
                                    option1 = dataItem["textRow"]
                                elif str(compare[1]) == str(dataItem["valueRow"]):
                                    value2 = formatdata(float(dataItem["average"]), point)
                                    count2 = int(dataItem["count"])
                                    option2 = dataItem["textRow"]
                        connectorText, percent, proportion, discriptionFrom, discriptionTo, numFrom, numTo, valueFrom, \
                        valueTo, valueCompare = "", "", "", "", "", "", "", "", "", ""
                        if connector == "": connector = ["", "", ""]
                        if len(connector) == 1: connector.append(connector[0])
                        if isinstance(value1, list):
                            if "top" in content["content"].keys():
                                value1Set, value2Set, count1Set, count2Set, option1Set, option2Set = \
                                    float(value1[0]), float(value2[0]), int(count1[0]), int(count2[0]), option1[0], \
                                    option2[0]
                                for value1Index,value1Item in enumerate(value1):
                                    if value1Index > 0:
                                        if value1Set < float(value1Item):
                                            value1Set = float(value1[value1Index])
                                            value2Set = float(value2[value1Index])
                                            count1Set = int(count1[value1Index])
                                            count2Set = int(count2[value1Index])
                                            option1Set = option1[value1Index]
                                            option2Set = option2[value1Index]
                                value1, value2, count1, count2, option1, option2 = \
                                    value1Set, value2Set, count1Set, count2Set, option1Set, option2Set
                            else:
                                discriptionFrom, discriptionTo, connectorText = ["","",""], ["", "",""], ["", "",""]
                                for valueInd, valueItem in enumerate(value1):
                                    if float(valueItem) - float(value2[valueInd]) > 0:
                                        if discriptionFrom[0] != "":
                                            discriptionFrom[0] += '、'
                                        discriptionFrom[0] += option1[valueInd]
                                        if discriptionTo[0] != "":
                                            discriptionTo[0] += '、'
                                        discriptionTo[0] += option2[valueInd]
                                        if connectorText[0] == "":connectorText[0] = connector[0]
                                    elif float(valueItem) - float(value2[valueInd]) < 0:
                                        if discriptionFrom[1] != "":
                                            discriptionFrom[1] += '、'
                                        discriptionFrom[1] += option1[valueInd]
                                        if discriptionTo[1] != "":
                                            discriptionTo[1] += '、'
                                        discriptionTo[1] += option2[valueInd]
                                        if connectorText[1] == "": connectorText[1] = connector[1]
                                    else:
                                        if discriptionFrom[2] != "":
                                            discriptionFrom[2] += '、'
                                        discriptionFrom[2] += option1[valueInd]
                                        if discriptionTo[2] != "":
                                            discriptionTo[2] += '、'
                                        discriptionTo[2] += option2[valueInd]
                                        if connectorText[2] == "": connectorText[2] = connector[2]
                        if not isinstance(value1, list):
                            discriptionFrom, discriptionTo, numFrom, numTo = option1, option2, str(count1), str(count2)
                            valueFrom, valueTo, valueCompare = \
                                formatdata(float(value1), point), formatdata(float(value2), point), ""
                            if abs(float(value1)) - abs(float(value2)) > 0:
                                valueCompare,connectorText = \
                                    formatdata(abs(float(value1)) - abs(float(value2)), point), connector[0]
                            elif abs(float(value1)) - abs(float(value2)) < 0:
                                valueCompare, connectorText = \
                                    formatdata(abs(float(value2)) - abs(float(value1)), point), connector[1]
                            else:
                                if str(connector[2]) != "":
                                    if "text2" in content["content"].keys() and \
                                            str(content["content"]["text2"]).strip() != "":
                                        discriptionword.append(content["content"]["text2"].
                                                               format(percent=percent, discriptionFrom=discriptionFrom,
                                                                      discriptionTo=discriptionTo, numFrom=numFrom,
                                                                      numTo=numTo, valueFrom=valueFrom,
                                                                      valueTo=valueTo))
                                    discriptionword.append(connector[2])
                            if count2 > 0:
                                percent = formatdata((float(count1) / float(count2)) * 100, point)
                                proportion = formatdata((float(count1) / float(count2)), point) + "︰1"
                        if len(discriptionword) == 0:
                            if isinstance(connectorText, list):
                                for connectorTextIndex, connectorTextItem in enumerate(connectorText):
                                    if connectorTextItem != "":
                                        if "text2" in content["content"].keys() and str(
                                                content["content"]["text2"]).strip() != "":
                                            discriptionword.append(content["content"]["text2"].format(
                                                discriptionFrom=discriptionFrom[connectorTextIndex],
                                                discriptionTo=discriptionTo[connectorTextIndex],
                                                connector=connectorTextItem))
                                        discriptionword.append(content["content"]["text"].format(
                                            discriptionFrom=discriptionFrom[connectorTextIndex],
                                            discriptionTo=discriptionTo[connectorTextIndex],
                                            connector=connectorTextItem))
                            else:
                                if "text2" in content["content"].keys() and str(content["content"]["text2"]).strip() != "":
                                    discriptionword.append(content["content"]["text2"].format(
                                        percent=percent, discriptionFrom=discriptionFrom,discriptionTo=discriptionTo,
                                        numFrom=numFrom,numTo=numTo, valueFrom=valueFrom, valueTo=valueTo))
                                discriptionword.append(content["content"]["text"].format(
                                    percent=percent,discriptionFrom=discriptionFrom,discriptionTo=discriptionTo,
                                    numFrom=numFrom,numTo=numTo,valueFrom=valueFrom,valueTo=valueTo,
                                    valueCompare=valueCompare,connector=connectorText, proportion=proportion))
                    if len(discriptionword) < 20:
                        for discriptionIndex in range(20 - len(discriptionword)):
                            discriptionword.append("")
                    text = text.format(*discriptionword)
                    text = replacetext(text, replaceText)
                else:
                    phrase = content["content"]["phrase"]
                    for phraseItem in phrase:
                        group = phraseItem["group"]
                        percent,count,casepercent,name,average,optionID,optionNM = \
                            float(0),0,float(0),"",float(0),"value","text"
                        if head["analysis"] == "comparemeans":
                            optionID, optionNM = "valueRow", "textRow"
                        if connector == "": connector = "或"
                        if isinstance(group,list):
                            for ind, groupItem in enumerate(group):
                                for dataItem in detailValid:
                                    if str(groupItem).strip() == str(dataItem[optionID]).strip() or \
                                            str(groupItem).strip() == str(dataItem[optionNM]).strip():
                                        count += int(dataItem["count"])
                                        if "validpercent" in dataItem.keys():
                                            if pointGroup == "":
                                                percent += float(dataItem["validpercent"])
                                            else:
                                                percent += float(str(formatdata(float(dataItem["validpercent"]),
                                                                                int(pointGroup) + 2)))
                                        if "casepercent" in dataItem.keys():
                                            if pointGroup == "":
                                                casepercent += float(dataItem["casepercent"])
                                            else:
                                                casepercent += float(str(formatdata(float(dataItem["casepercent"]),
                                                                                    int(pointGroup) + 2)))
                                        if "average" in dataItem.keys():
                                            if pointGroup == "":
                                                average += float(dataItem["average"])
                                            else:
                                                average += float(str(formatdata(float(dataItem["average"]),
                                                                                    int(pointGroup))))
                                        if name != "":
                                            name += connector
                                        name += "“" + str(dataItem[optionNM]).strip() + "”"
                        else:
                            for detailValidItem in detailValid:
                                if str(group).strip() == str(detailValidItem[optionID]).strip() or \
                                        str(group).strip() == str(detailValidItem[optionNM]).strip():
                                    count += int(detailValidItem["count"])
                                    if "validpercent" in detailValidItem.keys():
                                        percent += float(detailValidItem["validpercent"])
                                    if "casepercent" in detailValidItem.keys():
                                        casepercent += float(detailValidItem["casepercent"])
                                    if "average" in detailValidItem.keys():
                                        average += float(detailValidItem["average"])
                                    name = str(detailValidItem[optionNM]).strip()

                        if "text2" in phraseItem.keys() and len(discriptionword) == 0:
                            if name == "" and str(phraseItem["text2"]).find("name") > -1:
                                discriptionword.append("")
                            else:
                                discriptionword.append(phraseItem["text2"].
                                                       format(per=str(formatdata(percent * 100, point)) + units,
                                                              caseper=str(formatdata(casepercent * 100, point)) + units,
                                                              avg=str(formatdata(average, point)),
                                                              count=count,name=name))
                        else:
                            if name == "" and str(phraseItem["text"]).find("name") > -1:
                                discriptionword.append("")
                            else:
                                discriptionword.append(phraseItem["text"].
                                                       format(per=str(formatdata(percent * 100, point)) + units,
                                                              caseper=str(formatdata(casepercent * 100, point)) + units,
                                                              avg=str(formatdata(average, point)),
                                                              count=count,name=name))
                    if len(discriptionword) < 20:
                        for discriptionIndex in range(20-len(discriptionword)):
                            discriptionword.append("")
                    text = text.format(*discriptionword)
                    text = replacetext(text, replaceText)
        indexcount = 0
        if title != "":
            if title.find("[") > -1 :
                fromtext = title
            else:
                fromtext = "[" + fromtext + title + "]"
        else:
            fromtext = "[" + fromtext + "]"
        if bookMark != "":
            if str(os.path.abspath(os.curdir)).find("core") > 0:
                filePath = os.path.abspath(os.curdir).replace("core", "docx")
            else:
                filePath = os.path.join(os.path.abspath(os.curdir), "docx")
            discriptionJsonString, discriptionJsonPath = dict(discription=[], chartall=[]), \
                                                       os.path.join(filePath, 'charts', discriptionJson)
            if os.path.exists(discriptionJsonPath):
                with open(discriptionJsonPath, "r", encoding="utf-8") as f:
                    discriptionJsonString = json.load(f)
                    f.close()
            discriptionJsonString["discription"].append(dict(bookMark="PO_" + bookMark, style=style, text=text))
            with open(discriptionJsonPath, "w", encoding="utf-8") as fp:
                fp.write(json.dumps(discriptionJsonString, indent=4))
                fp.close()
            return None
        if wordHead != "" and len(documentWord.sections) > 0:
            for section in documentWord.sections:
                headWord = section.header
                for paragraph in headWord.paragraphs:
                    if str(paragraph.text).find(fromtext) > -1:
                        discriptionRun(paragraph, fromtext, text)
                        indexcount += 1
                        if indexcount >= countbreak:
                            return None
                if indexcount < countbreak:
                    for wordtext in headWord.part.element.iter():
                        if wordtext.tag.endswith(('AlternateContent', 'textbox')):
                            textString, textCount, textSave = "", 0, []
                            for ci in wordtext.iter():
                                textCount += 1
                                if ci.text is not None:
                                    textString += str(ci.text)
                                    textSave.append(textCount)
                                    if textString.find(fromtext) > -1:
                                        break
                                else:
                                    textString = ""
                                    textSave.clear()
                            if textString.find(fromtext) > -1:
                                textString, textCount = textString.replace(fromtext, text), 0
                                for ci in wordtext.iter():
                                    textCount += 1
                                    if ci.text is not None and textCount == textSave[0]:
                                        ci.text = textString
                                    else:
                                        if ci.text is not None and textCount in textSave:
                                            ci.text = ""
        else:
            for paragraph in documentWord.paragraphs:
                for runIndex in range(20):
                    if str(paragraph.text).find(fromtext) > -1:
                        if str(paragraph.text).strip() == fromtext and text.find('\n') > -1:
                            textGroup = text.split('\n')
                            for textIndex, textItem in enumerate(textGroup):
                                if textIndex == len(textGroup) - 1:
                                    paragraph.text = str(paragraph.text).replace(fromtext, textItem)
                                else:
                                    paragraph.insert_paragraph_before(textItem, paragraph.style)
                        else:
                            discriptionRun(paragraph, fromtext, text)
                        indexcount += 1
                        if str(paragraph.text).strip() == "，" or str(paragraph.text).strip() == "":
                            p = paragraph._element
                            p.getparent().remove(p)
                            # p._p = p._element = None
                            paragraph._p = paragraph._element = None
                        if indexcount >= countbreak and fromtext not in textDiscription and \
                                fromtext not in tableDiscription:
                            return None
                    else:
                        break
            if fromtext in textDiscription:
                for wordtext in documentWord.element.body.iter():
                    if wordtext.tag.endswith(('AlternateContent', 'textbox')):
                        textString, textCount, textSave = "", 0, []
                        for ci in wordtext.iter():
                            textCount += 1
                            if ci.text is not None:
                                textString += str(ci.text)
                                textSave.append(textCount)
                                if textString.find(fromtext) > -1:
                                    break
                            else:
                                textString = ""
                                textSave.clear()
                        if textString.find(fromtext) > -1:
                            textString, textCount = textString.replace(fromtext, text), 0
                            for ci in wordtext.iter():
                                textCount += 1
                                if ci.text is not None and textCount == textSave[0]:
                                    ci.text = textString
                                else:
                                    if ci.text is not None and textCount in textSave:
                                        ci.text = ""
            if fromtext in tableDiscription:
                for tableDiscriptionIndex, tableDiscriptionItem in enumerate(tableDiscription):
                    if fromtext == tableDiscriptionItem:
                        activeTable = documentWord.tables[tableIndexDiscription[tableDiscriptionIndex]]
                        for tableRowIndex in range(len(activeTable.rows)):
                            for tableColIndex in range(len(activeTable.columns)):
                                try:
                                    if str(activeTable.rows[tableRowIndex].cells[tableColIndex].text).find(
                                            fromtext) > -1:
                                        if text.find('|') > -1:
                                            textArray = text.split('|')
                                            table_cell_set(activeTable, tableRowIndex, tableColIndex, tableRowIndex,
                                                           textArray[0], fromtext)
                                            for colIndex in range(1, len(textArray)):
                                                table_cell_set(activeTable, tableRowIndex, tableColIndex + colIndex,
                                                               tableRowIndex, textArray[colIndex])
                                        else:
                                            table_cell_set(activeTable, tableRowIndex, tableColIndex, tableRowIndex,
                                                           text, fromtext)
                                except Exception as e:
                                    pass
    else:
        if isinstance(replaceText, list):
            if len(replaceText) == 1:replaceText.append(replaceText[0])
            replaceFrom = replaceText[0]
            replaceTo = replaceText[1]
            for replaceFromIndex, replaceFromItem in enumerate(replaceFrom):
                fromtext,text = str(replaceFromItem).strip(), ""
                if replaceFromIndex < len(replaceTo):text = str(replaceTo[replaceFromIndex])
                for replaceIndex in range(countbreak):
                    for paragraph in documentWord.paragraphs:
                        if str(paragraph.text).find(fromtext) > -1:
                            paragraph.text = str(paragraph.text).replace(fromtext, text)
    return None


def worddiscriptionTextAndTable(documentWord):
    textDiscription, tableDiscription, tableIndexDiscription = [], [], []
    for wordtext in documentWord.element.body.iter():
        if wordtext.tag.endswith(('AlternateContent', 'textbox')):
            textString, textCount, textSave = "", 0, []
            for ci in wordtext.iter():
                textCount += 1
                if ci.text is not None:
                    textString += str(ci.text)
                    textSave.append(textCount)
                    if textString.find('[') > -1 and textString.find(']') > 0:
                        textDiscription.append(textString[textString.find('['):textString.find(']') + 1])
                        break
                else:
                    textString = ""

    for activeTableIndex, activeTable in enumerate(documentWord.tables):
        for tableRowIndex in range(len(activeTable.rows)):
            for tableColIndex in range(len(activeTable.columns)):
                try:
                    if str(activeTable.rows[tableRowIndex].cells[tableColIndex].text).find(
                            '[') > -1 and str(activeTable.rows[tableRowIndex].cells[tableColIndex].text).find(
                            ']') > 0 and not str(activeTable.rows[tableRowIndex].cells[tableColIndex].text).find(
                            '[表') > -1:
                        paragraphs = activeTable.rows[tableRowIndex].cells[tableColIndex].paragraphs
                        for paragraph in paragraphs:
                            paragraphText = str(paragraph.text)
                            if str(paragraphText).find('[') > -1 and str(paragraphText).find(']') > 0:
                                for paragraphTextIndex in range(len(paragraphText)):
                                    tableDiscription.append(paragraphText[paragraphText.find
                                                                          ('['):paragraphText.find(']') + 1])
                                    tableIndexDiscription.append(activeTableIndex)
                                    paragraphText = paragraphText.replace\
                                        (tableDiscription[len(tableDiscription) - 1], '')
                                    if not (str(paragraphText).find('[') > -1 and str(paragraphText).find(']') > 0):
                                        break
                except Exception as e:
                    pass
    return textDiscription, tableDiscription, tableIndexDiscription


def worddiscriptionReplace(documentWord):
    replaceText, countbreak = [], 5
    replaceText.append(['此题无相关数据！！！！！，此题无相关数据！！！！！；',
                        '此题无相关数据！！！！！，此题无相关数据！！！！！。',
                        '此题无相关数据！！！！！，此题无相关数据！！！！！！',
                        '，此题无相关数据！！！！！，', '，此题无相关数据！！！！！；',
                        '，此题无相关数据！！！！！。','，此题无相关数据！！！！！！',
                        '；此题无相关数据！！！！！。', '；此题无相关数据！！！！！！',
                        '，“此题无相关数据！！！！！”，', '，“此题无相关数据！！！！！”；',
                        '，“此题无相关数据！！！！！”。','，“此题无相关数据！！！！！”！',
                        '；“此题无相关数据！！！！！”。','；“此题无相关数据！！！！！”！',
                        '，；','，。','，！','。。','，“”；','，“”。','，“”！','。“”。','“”',
                        '。“此题无相关数据！！！！！”。','。此题无相关数据！！！！！。'])
    replaceText.append(['','','','，','；','。','！','。','！','，','；','。','！','。','！','；','。','！','。',
                        '；','。','！','。','','。','。'])
    if isinstance(replaceText, list):
        if len(replaceText) == 1:replaceText.append(replaceText[0])
        replaceFrom = replaceText[0]
        replaceTo = replaceText[1]
        for replaceIndex in range(countbreak):
            replaceFlag = False
            for replaceFromIndex, replaceFromItem in enumerate(replaceFrom):
                fromtext,text = str(replaceFromItem).strip(), ""
                if replaceFromIndex < len(replaceTo):text = str(replaceTo[replaceFromIndex])
                for paragraph in documentWord.paragraphs:
                    if str(paragraph.text).find(fromtext) > -1:
                        paragraph.text = str(paragraph.text).replace(fromtext, text)
                        replaceFlag = True
            if not replaceFlag:break
    return None


def discriptionRun(paragraph, fromtext, text):
    runList, runText, runFlag, runListFlag = [], "", False, False
    for runIndex, runItem in enumerate(paragraph.runs):
        if runItem.text.find("[") > -1 or runFlag:
            if runItem.text.find("]") > -1:
                runList.append(runIndex)
                runText += runItem.text
                runTextBefore = ""
                runTextAfter = ""
                if runText.find(fromtext) > -1:
                    if runText != fromtext:
                        if runText.find(fromtext) == 0:
                            runTextAfter = runText.replace(fromtext, "")
                        else:
                            runTextRetain = runText.split(fromtext)
                            runTextBefore = runTextRetain[0]
                            if len(runTextRetain) > 1: runTextAfter = runTextRetain[1]
                    for runListItem in runList:
                        paragraph.runs[runListItem].text = ""
                    if text.find('“') > -1 and text.find('”') > -1:
                        if runList[0] > 0 and runList[len(runList) - 1] < len(paragraph.runs) - 1:
                            if paragraph.runs[runList[0] - 1].text.find('“') > -1 and \
                                    paragraph.runs[runList[len(runList) - 1] + 1].text.find('”') == 0:
                                runTextBefore = paragraph.runs[runList[0] - 1].text.replace('“', '') + runTextBefore
                                paragraph.runs[runList[len(runList) - 1] + 1].text = \
                                    paragraph.runs[runList[len(runList) - 1] + 1].text.replace('”', '')
                                for runListIndex, runListItem in enumerate(runList):
                                    runList[runListIndex] = runListItem - 1
                    if len(runList) == 1:
                        paragraph.runs[runList[0]].text = runTextBefore + text + runTextAfter
                    elif len(runList) == 2:
                        if runTextBefore != "":
                            paragraph.runs[runList[0]].text = runTextBefore
                            paragraph.runs[runList[len(runList) - 1]].text = text + runTextAfter
                        else:
                            paragraph.runs[runList[0]].text = text + runTextAfter
                    else:
                        if runTextBefore != "":
                            paragraph.runs[runList[0]].text = runTextBefore
                            paragraph.runs[runList[1]].text = text
                            paragraph.runs[runList[len(runList) - 1]].text = runTextAfter
                        else:
                            paragraph.runs[runList[0]].text = text
                            paragraph.runs[runList[len(runList) - 1]].text = runTextAfter
                    return True
                else:
                    if runItem.text.find("[") > -1 and runItem.text.find("]") > -1:
                        runList, runText, runFlag = [], "", False
                    elif runItem.text.find("[") > -1:
                        runList = [runIndex]
                        runText = runItem.text
                        runFlag = True
                    else:
                        runList, runText, runFlag = [], "", False
            else:
                runList.append(runIndex)
                runText += runItem.text
                runFlag = True
    return None


def compareReturn(comStr, valueFrom, valueTo, detailValidItem):
    if isinstance(comStr, list):
        valueGroup = []
        for comIndex in range(len(comStr)):
            if valueFrom[comIndex] == "text":valueFrom[comIndex] = "optiontext"
            if valueFrom[comIndex] in detailValidItem.keys():
                if is_number(valueTo[comIndex]):
                    valueToItem = float(valueTo[comIndex])
                else:
                    valueToItem = valueTo[comIndex]
                if str(comStr[comIndex]).strip() == "=" or str(comStr[comIndex]).strip() == "==":
                    valueGroup.append(eq(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == "<":
                    valueGroup.append(lt(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == "<=":
                    valueGroup.append(le(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == ">":
                    valueGroup.append(gt(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == ">=":
                    valueGroup.append(ge(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == "!=" or str(comStr[comIndex]).strip() == "<>":
                    valueGroup.append(ne(detailValidItem[valueFrom[comIndex]], valueToItem))
                elif str(comStr[comIndex]).strip() == "in":
                    if str(detailValidItem[valueFrom[comIndex]]).strip() in valueToItem:
                        valueGroup.append(True)
                else:
                    valueGroup.append(None)
            else:
                valueGroup.append(None)
        for valueItem in valueGroup:
            if not valueItem:
                return False
        return True
    else:
        if is_number(valueTo):
            valueToItem = float(valueTo)
        else:
            valueToItem = valueTo
        if valueFrom == "text":valueFrom = "optiontext"
        if valueFrom in detailValidItem.keys():
            if str(comStr).strip() == "=" or str(comStr).strip() == "==":
                return eq(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == "<":
                return lt(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == "<=":
                return le(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == ">":
                return gt(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == ">=":
                return ge(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == "!=" or str(comStr).strip() == "<>":
                return ne(detailValidItem[valueFrom], valueToItem)
            elif str(comStr).strip() == "in":
                if str(detailValidItem[valueFrom]).strip() in valueToItem:
                    return True
            else:
                return None
        else:
            return None


def wordcharts(documentWord, contentRow, json_data, chartJson, allReplace):
    content=contentRow["content"]
    datatarget,label,data1,data2 = dict(Xaxis=[], Yaxis=[]),[],dict(data=[]),[]
    datadef = lambda: None if "data" not in content.keys() else content["data"]
    pointdef = lambda:2 if "point" not in content.keys() else content["point"]
    unitsdef = lambda:"" if "units" not in content.keys() else content["units"]
    widthdef = lambda:13.83 if "width" not in content.keys() else float(content["width"])
    heightdef = lambda:6.67 if "height" not in content.keys() else float(content["height"])
    phrasedef = lambda: "" if "phrase" not in content.keys() else content["phrase"]
    chartnamedef = lambda: "" if "chartname" not in content.keys() else content["chartname"]
    dataN, point,units,width,height,phrase,chartname,chartflag = datadef(), pointdef(), unitsdef(), widthdef(), \
                                                                 heightdef(), phrasedef(), chartnamedef(), False
    if dataN is not None:
        if isinstance(dataN,list):
            fromtext,detailValid = "图",[]
            if "group" in content.keys():
                if "groupID" in content.keys():
                    for index, itemdata in enumerate(dataN):
                        datasource = json.loads(json_data[itemdata])
                        head = datasource["head"][0]
                        fromtext = fromtext + "-" + head["variableID"]
                    group,outValue = content["group"],[]
                    for index in range(len(group)):
                        outValue.append(0)
                    for indexgroup, itemgroup in enumerate(group):
                        groupValue=group[indexgroup]
                        groupColumnID=content["groupID"][indexgroup]
                        for indexgroupID, itemgroupID in enumerate(groupColumnID):
                            sumdata = 0
                            for index, itemdata in enumerate(dataN):
                                datasource = json.loads(json_data[itemdata])
                                head = datasource["head"][0]
                                if head["count"] != 0 and head["variableID"]==itemgroupID:
                                    detailValidFrom,chartflag = datasource["detailValid"],True
                                    for dataItem in detailValidFrom:
                                        for indexgroupValue,itemgroupValue in enumerate(groupValue):
                                            if float(str(dataItem["value"])) == float(str(itemgroupValue)):
                                                sumdata += float(dataItem[content["outColumn"]])
                            outValue[indexgroup]=sumdata
                            if indexgroup==0:
                                detailValid.append(dict(value=itemgroupID, text=phrase[indexgroupID],
                                                        outValue=outValue))
                            else:
                                for detailIndex,detailItem in enumerate(detailValid):
                                    if str(phrase[indexgroupID]).strip()==str(detailItem["text"]).strip():
                                        detailValid[detailIndex]["outValue"][indexgroup]=outValue[indexgroup]
                else:
                    group = content["group"]
                    for index, itemdata in enumerate(dataN):
                        datasource = json.loads(json_data[itemdata])
                        head = datasource["head"][0]
                        fromtext = fromtext + "-" + head["variableID"]
                        if head["count"] != 0:
                            detailValidFrom,outValue,chartflag = datasource["detailValid"],0,True
                            if isinstance(group, list):
                                for dataItem in detailValidFrom:
                                    for indexID, itemID in enumerate(group):
                                        if float(str(dataItem["value"])) == float(str(itemID)):
                                            outValue+=float(dataItem[content["outColumn"]])
                            else:
                                for dataItem in detailValidFrom:
                                    if float(str(dataItem["value"])) == float(str(group)):
                                        outValue += float(dataItem[content["outColumn"]])
                            detailValid.append(dict(value=head["variableID"], text=phrase[index], outValue=outValue))
            else:
                outValue = []
                for index in range(len(dataN)):
                    outValue.append(0)
                for index, itemdata in enumerate(dataN):
                    datasource = json.loads(json_data[itemdata])
                    head = datasource["head"][0]
                    fromtext = fromtext + "-" + head["variableID"]
                    if head["count"] != 0:
                        chartflag = True
                        if head["analysis"] == "frequency" or head["analysis"] == "multiple" or \
                                head["analysis"] == "wordcloud":
                            detailValidFrom = datasource["detailValid"]
                            detailValidFrom.sort(key=lambda x: x["value"], reverse=False)
                            for dataItem in detailValidFrom:
                                if index == 0:
                                    setoutValue = copy.deepcopy(outValue)
                                    setoutValue[index] = dataItem[content["outColumn"]]
                                    detailValid.append(dict(value=dataItem["value"], text=dataItem["text"],
                                                            outValue=setoutValue))
                                else:
                                    flag,rowNo = False, -1
                                    for detailIndex,detailItem in enumerate(detailValid):
                                        if dataItem["text"]==detailItem["text"]:
                                            detailValid[detailIndex]["outValue"][index]=dataItem[content["outColumn"]]
                                            flag,rowNo = True,detailIndex
                                            break
                                    if not flag:
                                        setoutValue = copy.deepcopy(outValue)
                                        setoutValue[index] = dataItem[content["outColumn"]]
                                        detailValid.append(dict(value=dataItem["value"], text=dataItem["text"],
                                                                outValue=setoutValue))
                                    else:
                                        setoutValue = copy.deepcopy(detailValid[rowNo]["outValue"])
                                        detailValid[rowNo]["outValue"] = setoutValue
                        elif head["analysis"] == "means":
                            detailValid.append(dict(value=999999,text=phrase[index],outValue=head[content["outColumn"]]))
                        elif head["analysis"] == "comparemeans":
                            detailValidFrom = datasource["detailValid"]
                            if content["sort"] == "avg":
                                detailValid.sort(key=lambda x: x["average"], reverse=False)
                            elif content["sort"] == "-avg":
                                detailValid.sort(key=lambda x: x["average"], reverse=True)
                            for dataItem in detailValidFrom:
                                detailValid.append(dict(value=dataItem["valueRow"], text=dataItem["textRow"],
                                                        outValue=dataItem[content["outColumn"]]))
            if chartflag:
                if "sort" in content.keys():
                    if content["sort"] == "id":
                        detailValid.sort(key=lambda x: x["value"], reverse=False)
                    elif content["sort"] == "-id":
                        detailValid.sort(key=lambda x: x["value"], reverse=True)
                    elif content["sort"] == "outValue":
                        detailValid.sort(key=lambda x: x["outValue"], reverse=False)
                    elif content["sort"] == "-outValue":
                        detailValid.sort(key=lambda x: x["outValue"], reverse=True)
                    elif content["sort"] == "0":
                        detailValid.sort(key=lambda x: x["outValue"][0], reverse=False)
                    elif content["sort"] == "-0":
                        detailValid.sort(key=lambda x: x["outValue"][0], reverse=True)
                    elif content["sort"] == "1":
                        detailValid.sort(key=lambda x: x["outValue"][1], reverse=False)
                    elif content["sort"] == "-1":
                        detailValid.sort(key=lambda x: x["outValue"][1], reverse=True)
                # Xaxis X轴赋值
                if "label" in content.keys() and "seriesname" in content.keys():
                    seriesname=content["seriesname"]
                    for index,itemseries in enumerate(seriesname):
                        label.append(itemseries)
                else:
                    for dataItem in detailValid:
                        label.append(dataItem["text"])
                # Yaxis Y轴赋值
                if isinstance(detailValid[0]["outValue"], list):
                    if "label" in content.keys() and "seriesname" in content.keys():
                        for dataItem in detailValid:
                            data2 = []
                            for index,outItem in enumerate(dataItem["outValue"]):
                                if content["outColumn"]=="validpercent" or content["outColumn"]=="casepercent":
                                    data2.append(formatdata(float(outItem) * 100, point, "c"))
                                elif content["outColumn"]=="average":
                                    data2.append(formatdata(float(outItem), point, "c"))
                                else:
                                    data2.append(outItem)
                            data1["seriesname"] = dataItem["text"]
                            data1["data"] = data2
                            data1["axisLabel"] = formatchart(units, point)
                            datatarget["Yaxis"].append(copy.deepcopy(data1))
                    else:
                        seriesname = content["seriesname"]
                        for index, outItem in enumerate(seriesname):
                            data2 = []
                            for dataItem in detailValid:
                                if content["outColumn"] == "validpercent" or content["outColumn"] == "casepercent":
                                    data2.append(formatdata(float(dataItem["outValue"][index]) * 100, point, "c"))
                                elif content["outColumn"] == "average":
                                    data2.append(formatdata(float(dataItem["outValue"][index]), point, "c"))
                                else:
                                    data2.append(dataItem["outValue"][index])
                            data1["data"] = data2
                            data1["axisLabel"] = formatchart(units, point)
                            data1["seriesname"] = outItem
                            datatarget["Yaxis"].append(copy.deepcopy(data1))
                else:
                    data2 = []
                    for dataItem in detailValid:
                        if content["outColumn"] == "validpercent" or content["outColumn"] == "casepercent":
                            data2.append(formatdata(float(dataItem["outValue"]) * 100, point, "c"))
                        elif content["outColumn"] == "average":
                            data2.append(formatdata(float(dataItem["outValue"]), point, "c"))
                        else:
                            data2.append(dataItem["outValue"])
                    data1["data"] = data2
                    data1["axisLabel"] = formatchart(units, point)
                    if "seriesname" in content.keys():
                        data1["seriesname"] = content["seriesname"]
                    else:
                        data1["seriesname"] = ""
                    datatarget["Yaxis"].append(data1)
        else:
            datasource = json.loads(json_data[content["data"]])
            detailValid = datasource["detailValid"]
            head=datasource["head"][0]
            if head["analysis"]=="crosstabs" or head["analysis"]=="comparemeans":
                fromtext="图-" + head["RowID"] + "-" + head["ColumnID"]
            else:
                fromtext="图-" + head["variableID"]
            if head["count"] != 0:
                chartflag = True
                if head["analysis"]=="frequency" or head["analysis"]=="multiple" or head["analysis"]=="wordcloud":
                    if content["sort"]=="id":
                        detailValid.sort(key=lambda x: x["value"],reverse=False)
                    elif content["sort"]=="-id":
                        detailValid.sort(key=lambda x: x["value"],reverse=True)
                    elif content["sort"]=="per":
                        if head["analysis"]=="multiple":
                            detailValid.sort(key=lambda x: x["casepercent"],reverse=False)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=False)
                    elif content["sort"]=="-per":
                        if head["analysis"]=="multiple":
                            detailValid.sort(key=lambda x: x["casepercent"],reverse=True)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=True)
                    elif content["sort"] == "avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=False)
                    elif content["sort"] == "-avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=True)
                    else:
                        detailValid.sort(key=lambda x: x["value"],reverse=False)
                    if "exception" in content.keys():
                        deletenum = -1
                        for num in range(0, len(detailValid)):
                            optionname = detailValid[num]["text"]
                            if str(optionname).strip() == str(content["exception"]).strip():
                                rowdetail = copy.deepcopy(detailValid[num])
                                deletenum = num
                                detailValid.append(rowdetail)
                        if deletenum > -1:
                            del detailValid[deletenum]
                    #Xaxis X轴赋值
                    for dataItem in detailValid:
                        label.append(dataItem["text"])

                    #Yaxis Y轴赋值
                    if "outColumn" in content:
                        outValue=content["outColumn"]
                        if isinstance(outValue, list):
                            for ind, outValueItem in enumerate(outValue):
                                data2=[]
                                for dataItem in detailValid:
                                    if outValueItem=="casepercent" or outValueItem=="validpercent":
                                        data2.append(formatdata(float(dataItem[outValueItem]) * 100, point, "c"))
                                    else:
                                        data2.append(dataItem[outValueItem])
                                data1["data"]=data2
                                data1["seriesname"] = ""
                                if "seriesname" in content:
                                    seriesname=content["seriesname"]
                                    data1["seriesname"]=seriesname[ind]
                                if (outValueItem=="casepercent" or outValueItem=="validpercent") and chartname != "" \
                                        and chartname != "pie":
                                    data1["axisLabel"]=formatchart(units,point)
                                datatarget["Yaxis"].append(copy.deepcopy(data1))
                        else:
                            for dataItem in detailValid:
                                if str(outValue).find("per") > -1:
                                    data2.append(formatdata(float(dataItem[outValue]) * 100, point, "c"))
                                else:
                                    data2.append(dataItem[outValue])
                            data1["data"] = data2
                            data1["seriesname"] = ""
                            if chartname != "" and chartname != "pie":
                                data1["axisLabel"] = formatchart(units, point)
                            datatarget["Yaxis"].append(data1)
                    else:
                        for dataItem in detailValid:
                            if head["analysis"]=="multiple":
                                data2.append(formatdata(float(dataItem["casepercent"]) * 100, point, "c"))
                            else:
                                data2.append(formatdata(float(dataItem["validpercent"]) * 100, point, "c"))
                        data1["data"]=data2
                        data1["seriesname"] = ""
                        if chartname != "" and chartname != "pie":
                            data1["axisLabel"]=formatchart(units,point)
                        datatarget["Yaxis"].append(data1)
                elif head["analysis"]=="crosstabs":
                    if content["sort"]=="-pergroup" or content["sort"]=="pergroup":
                        detailValid=datasource["detailValidgroup"]
                        if content["sort"]=="-pergroup":
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=True)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=False)
                    labelkey=dict(id=[], name=[])
                    labelkeyY=dict(id=[], name=[])
                    if "label" in content.keys():
                        if content["label"]=="RowID" or content["label"]=="-RowID":
                            for dataItem in detailValid:
                                if dataItem["valueRow"] not in labelkey["id"]:
                                    labelkey["id"].append(dataItem["valueRow"])
                                    labelkey["name"].append(dataItem["textRow"])
                                if dataItem["valueColumn"] not in labelkeyY["id"]:
                                    labelkeyY["id"].append(dataItem["valueColumn"])
                                    labelkeyY["name"].append(dataItem["textColumn"])
                            if content["label"]=="RowID":
                                labelkey.sort(key=lambda x: x["id"],reverse=False)
                            else:
                                labelkey.sort(key=lambda x: x["id"],reverse=True)
                        else:
                            for dataItem in detailValid:
                                if dataItem["valueColumn"] not in labelkey["id"]:
                                    labelkey["id"].append(dataItem["valueColumn"])
                                    labelkey["name"].append(dataItem["textColumn"])
                                if dataItem["valueRow"] not in labelkeyY["id"]:
                                    labelkeyY["id"].append(dataItem["valueRow"])
                                    labelkeyY["name"].append(dataItem["textColumn"])
                            if content["label"]=="valueColumn":
                                labelkey.sort(key=lambda x: x["id"],reverse=False)
                            else:
                                labelkey.sort(key=lambda x: x["id"],reverse=True)
                        if content["sort"]=="id":
                            labelkeyY.sort(key=lambda x: x["id"],reverse=False)
                        elif content["sort"]=="-id":
                            labelkeyY.sort(key=lambda x: x["id"],reverse=True)
                        if content["label"]=="RowID" or content["label"]=="-RowID":
                            value="valueRow"
                            valueY="valueColumn"
                        else:
                            value="valueColumn"
                            valueY="valueRow"
                        for n in range(len(labelkey["id"])):
                            data2.append(formatdata(0,point, "c"))
                        for indY,labelkeyYItem in enumerate(labelkeyY["id"]):
                            for n in range(len(labelkey["id"])):
                                data2[n]=formatdata(0,point, "c")
                            if content["sortYaxis"]=="id" or content["sortYaxis"]=="-id":
                                data1["seriesid"]=labelkeyY["id"][indY]
                            else:
                                data1["seriesid"]=0
                            for ind, labelkeyItem in enumerate(labelkey["id"]):
                                for dataItem in detailValid:
                                    if dataItem[valueY]==labelkeyYItem and dataItem[value]==labelkeyItem:
                                        data2[labelkey["id"].index(labelkeyItem)]=\
                                            formatdata(float(dataItem["validpercent"]) * 100, point, "c")
                                        if content["sortYaxis"]!="id" and content["sortYaxis"]!="-id" \
                                                and abs(int(content["sortYaxis"]))==dataItem[value]:
                                            data1["seriesid"]=float(dataItem["validpercent"])
                            data1["data"]=data2
                            data1["axisLabel"]=formatchart(units,point)
                            data1["seriesname"]=labelkeyY["name"][indY]
                            datatarget["Yaxis"].append(copy.deepcopy(data1))
                        if "-" in content["sortYaxis"]:
                            datatarget["Yaxis"].sort(key=lambda x: x["seriesid"],reverse=True)
                        else:
                            datatarget["Yaxis"].sort(key=lambda x: x["seriesid"],reverse=False)
                    else:
                        for dataItem in detailValid:
                            if dataItem["valueRow"] not in labelkey["id"]:
                                labelkey["id"].append(dataItem["valueRow"])
                                labelkey["name"].append(dataItem["textRow"])
                    # Xaxis X轴赋值
                    for labelkeyItem in labelkey:
                        label.append(labelkeyItem["name"])
                elif head["analysis"]=="comparemeans":
                    if content["sort"]=="id":
                        detailValid.sort(key=lambda x: x["valueRow"],reverse=False)
                    elif content["sort"]=="-id":
                        detailValid.sort(key=lambda x: x["valueRow"],reverse=True)
                    elif content["sort"]=="avg":
                        detailValid.sort(key=lambda x: x["average"],reverse=False)
                    elif content["sort"]=="-avg":
                        detailValid.sort(key=lambda x: x["average"],reverse=True)
                    elif content["sort"]=="median":
                        detailValid.sort(key=lambda x: x["median"],reverse=False)
                    elif content["sort"]=="-median":
                        detailValid.sort(key=lambda x: x["median"],reverse=True)
                    else:
                        detailValid.sort(key=lambda x: x["valueRow"],reverse=False)
                    # Xaxis X轴赋值
                    for dataItem in detailValid:
                        label.append(dataItem["textRow"])
                    for dataItem in detailValid:
                        if content["sort"]=="median" or content["sort"]=="-median":
                            data2.append(formatdata(float(dataItem["median"]), point, "c"))
                        else:
                            data2.append(formatdata(float(dataItem["average"]),point, "c"))
                    data1["data"]=data2
                    data1["seriesname"] = ""
                    data1["axisLabel"]=formatchart(units,point)
                    datatarget["Yaxis"].append(data1)
        fromtext = "[" + fromtext + "]"
        if chartflag:
            if contentRow["type"] == "chart":
                if "wordnum" in content.keys() and "show" in content.keys():
                    datatarget["Xaxis"].append(dict(axisLabel=dict(label=label),wordnum=content["wordnum"],
                                                    show=content["show"]))
                else:
                    if "wordnum" in content.keys():
                        datatarget["Xaxis"].append(dict(axisLabel=dict(label=label),wordnum=content["wordnum"]))
                    elif "show" in content.keys():
                        datatarget["Xaxis"].append(dict(axisLabel=dict(label=label),show=content["show"]))
                    else:
                        datatarget["Xaxis"].append(dict(axisLabel=dict(label=label)))
                # 数据调用
                if str(os.path.abspath(os.curdir)).find("core") > 0:
                    filePath = os.path.abspath(os.curdir).replace("core", "docx")
                else:
                    filePath = os.path.join(os.path.abspath(os.curdir), "docx")
                chartjson = os.path.join(filePath,'charts',str(content["chartjson"]))
                if str(chartjson).find(".json") < 0:
                    chartjson += ".json"
                with open(chartjson,"r",encoding="utf-8") as f:
                    datajson=json.load(f)
                    f.close()
                datajson['Xaxis']=datatarget['Xaxis']
                datajson['Yaxis']=datatarget['Yaxis']
                if "textstyle" in datajson.keys():
                    if "format" in datajson['textstyle'].keys():
                        #datajson['textstyle']['format'] = "." + str(point) + "%"
                        datajson['textstyle']['format'] = "." + str(point) + "f"
                filename=str(datajson['savefig']['filename']) + MyGuid()
                picname=os.path.join(filePath,'charts',filename)
                datajson['savefig']['filename'] = picname
                if chartname == "bar":
                    datajson["legend"]["ncol"] = str(len(datatarget['Yaxis']))
                    bar(datajson)
                elif chartname == "stackbar":
                    datajson["legend"]["ncol"] = str(len(datatarget['Yaxis']))
                    stackbar(datajson)
                elif chartname == "stackbarh":
                    datajson["legend"]["ncol"] = str(len(datatarget['Yaxis']))
                    stackbarh(datajson)
                elif chartname == "barh":
                    datajson["legend"]["ncol"]=str(len(datatarget['Yaxis']))
                    barh(datajson)
                elif chartname == "rl_barh":
                    rl_barh(datajson)
                elif chartname == "plot":
                    plot(datajson)
                elif chartname == "plots":
                    datajson["legend"]["ncol"] = str(len(datatarget['Yaxis']))
                    plots(datajson)
                elif chartname == "multiplot":
                    multiplot(datajson)
                elif chartname == "pie":
                    pie(datajson)
                elif chartname == "pies":
                    pies(datajson)
                elif chartname == "scatter":
                    scatter(datajson)
                elif chartname == "radar":
                    radar(datajson)
                elif chartname == "plot_bar":
                    plot_bar(datajson)
                elif chartname == "pic_pie_bar":
                    pic_pie_bar(datajson)
                elif chartname == "map":
                    pic_map(datajson)
                elif chartname == "pictorial_bar_horizon2":
                    pictorial_bar_horizon2(datajson)
                for paragraph in documentWord.paragraphs:
                    if str(paragraph.text).find(fromtext) > -1:
                        paragraph.text=""
                        run=paragraph.add_run()
                        run.add_picture(picname+'.png', height=Cm(height))
                        os.remove(picname + '.png')
                        return None
                for activeTable in documentWord.tables:
                    for index in range(len(activeTable.rows)):
                        for col in range(len(activeTable.columns)):
                            if str(activeTable.cell(index, col).paragraphs[0].text).find(fromtext) > -1:
                                activeTable.cell(index, col).paragraphs[0].text = ""
                                run = activeTable.cell(index, col).paragraphs[0].add_run()
                                run.add_picture(picname+'.png', height=Cm(height))
                                os.remove(picname + '.png')
                                return None
            else:
                rowStardef = lambda: "" if "rowStar" not in content.keys() else content["rowStar"]
                parameterdef = lambda: "" if "parameter" not in content.keys() else content["parameter"]
                chartfiledef = lambda: "" if "chartfile" not in content.keys() else content["chartfile"]
                dataLabelColdef = lambda: "" if "dataLabelCol" not in content.keys() else content["dataLabelCol"]
                tableColdef = lambda: "" if "tableCol" not in content.keys() else content["tableCol"]
                colordef = lambda: "" if "color" not in content.keys() else content["color"]
                colorColdef = lambda: "" if "colorCol" not in content.keys() else content["colorCol"]
                rowStar, parameter, chartfile, dataLabelCol, tableCol, color, colorCol = \
                    rowStardef(), parameterdef(), chartfiledef(), dataLabelColdef(),tableColdef(), colordef(),colorColdef()
                datasource,datahead, wordChartJson = [], [""], {}
                for index in range(len(datatarget["Yaxis"])):
                    datahead.append(datatarget["Yaxis"][index]["seriesname"])
                datasource.append(datahead)
                for index in range(len(datatarget["Yaxis"])):
                    for j in range(len(datatarget["Yaxis"][index]["data"])):
                        if index == 0:
                            if j < len(label):
                                datadetail = [label[j]]
                            else:
                                datadetail = [""]
                            datadetail.append(datatarget["Yaxis"][index]["data"][j])
                            datasource.append(datadetail)
                        else:
                            if j + 1 < len(datasource):
                                datasource[j + 1].append(datatarget["Yaxis"][index]["data"][j])
                if str(os.path.abspath(os.curdir)).find("core") > 0:
                    filePath = os.path.abspath(os.curdir).replace("core", "docx")
                else:
                    filePath = os.path.join(os.path.abspath(os.curdir), "docx")
                chartfilePath, chartJsonPath = "", os.path.join(filePath, 'charts', chartJson)
                if isinstance(chartfile, list):
                    if len(datasource) > int(chartfile[1]):
                        chartfilePath = os.path.join(filePath, 'charts', chartfile[2])
                    else:
                        chartfilePath = os.path.join(filePath, 'charts', chartfile[0])
                chartJsonString = dict(discription=[],chartall=[])
                if os.path.exists(chartJsonPath):
                    with open(chartJsonPath, "r", encoding="utf-8") as f:
                        chartJsonString = json.load(f)
                        f.close()
                chartJsonString["chartall"].append(dict(fromtext=fromtext, chartfilePath=chartfilePath,
                                                        datasource=datasource, rowStar=rowStar, parameter=parameter,
                                                        dataLabelCol=dataLabelCol, tableCol=tableCol, color=color,
                                                        colorCol=colorCol, units=units))
                with open(chartJsonPath, "w") as fp:
                    fp.write(json.dumps(chartJsonString, indent=4))
                    fp.close()
        else:
            text = "此题无相关数据！！！！！"
            for paragraph in documentWord.paragraphs:
                if str(paragraph.text).find(fromtext) > -1:
                    paragraph.text = text
                    return None
            for activeTable in documentWord.tables:
                for index in range(len(activeTable.rows)):
                    for col in range(len(activeTable.columns)):
                        if str(activeTable.cell(index, col).paragraphs[0].text).find(fromtext) > -1:
                            activeTable.cell(index, col).paragraphs[0].text = text
                            return None
    else:
        titledef = lambda: "" if "title" not in content.keys() else content["title"]
        rowTextdef = lambda: "" if "rowText" not in content.keys() else content["rowText"]
        outColumndef = lambda: "" if "outColumn" not in content.keys() else content["outColumn"]
        unitsBeforedef = lambda: "" if "unitsBefore" not in content.keys() else content["unitsBefore"]
        unitsAfterdef = lambda: "" if "unitsAfter" not in content.keys() else content["unitsAfter"]
        sortFirstdef = lambda: [] if "sortFirst" not in content.keys() else content["sortFirst"]
        sortLastdef = lambda: [] if "sortLast" not in content.keys() else content["sortLast"]
        positiondef = lambda: "" if "position" not in content.keys() else content["position"]
        displayRowdef = lambda: "" if "displayRow" not in content.keys() else content["displayRow"]
        displayTextdef = lambda: "" if "displayText" not in content.keys() else content["displayText"]
        chartLabelColdef = lambda: "" if "chartLabelCol" not in content.keys() else content["chartLabelCol"]
        replaceTextdef = lambda: "" if "replaceText" not in content.keys() else content["replaceText"]
        zeroFilldef = lambda: "" if "zeroFill" not in content.keys() else str(content["zeroFill"])
        phraseDatadef = lambda: "" if "phraseData" not in content.keys() else content["phraseData"]
        title, rowText, outColumn, unitsBefore, unitsAfter, fromtext, detailValid, columnMax, chartLabelCol = \
            titledef(), rowTextdef(), outColumndef(), unitsBeforedef(), unitsAfterdef(), "图", [], 0, chartLabelColdef()
        sortFirst, sortLast, position, displayRow, displayText, replaceText, zeroFill, phraseData, columnStringBack = \
            sortFirstdef(),sortLastdef(),positiondef(),displayRowdef(),displayTextdef(),replaceTextdef(),\
            zeroFilldef(), phraseDatadef(), {}
        if position == '[图92]':
            testFlag = True
        if allReplace is not None:
            if isinstance(replaceText, str) and replaceText == "":
                replaceText = allReplace
            else:
                if isinstance(replaceText, list):
                    for replace in allReplace[0]:
                        replaceText[0].append(replace)
                    for replace in allReplace[1]:
                        replaceText[1].append(replace)
        if len(sortFirst) != 0:
            rowNo, sortAll = -99999, sortFirst
        else:
            rowNo, sortAll = 99999, sortLast
        if rowText != "":
            detailValidTotal = rowDataProcess(outColumn, rowText, phrase, "", rowNo, sortAll, json_data, False,
                                              phraseData, point)
            for detailValidTotalItem in detailValidTotal:
                if len(detailValid) == 0:
                    detailValid = detailValidTotalItem
                else:
                    for detailValidItem in detailValidTotalItem:
                        detailValid.append(detailValidItem)
            for detailItem in detailValid:
                if detailItem["columnMax"] > columnMax: columnMax = detailItem["columnMax"]
        else:
            for columnIndex in range(len(outColumn)):
                detailValid.append(dict(value=int(columnIndex + 1)))
                if isinstance(outColumn[columnIndex], list):
                    if len(outColumn[columnIndex]) > columnMax: columnMax = len(outColumn[columnIndex])
                    for indexCol in range(len(outColumn[columnIndex])):
                        detailValid = outDataProcess(outColumn[columnIndex][indexCol], indexCol, rowText, phrase,
                                                     json_data, detailValid, columnIndex, False, phraseData, point,
                                                     "", columnStringBack)
                else:
                    if len(outColumn) > columnMax: columnMax = len(outColumn)
                    detailValid = outDataProcess(outColumn[columnIndex], columnIndex, rowText, phrase, json_data,
                                                 detailValid, -1, False, phraseData, point, "", columnStringBack)
        detailRemove, indexStar = [], 1
        if rowText != "":indexStar = 0
        for detailIndex, detailItem in enumerate(detailValid):
            removeFlag = True
            for indexColumn in range(indexStar, columnMax):
                if detailItem["column" + str(indexColumn)] is not None and \
                    str(detailItem["column" + str(indexColumn)]).strip() != ""and \
                    str(detailItem["columnName" + str(indexColumn)]).strip() != "固定值":
                    if is_number(sort_key(detailItem["column" + str(indexColumn)], None)) and \
                            float(str(sort_key(detailItem["column" + str(indexColumn)], None))) != 0.0:
                        removeFlag = False
                    if str(detailItem["column" + str(indexColumn)]).strip() == "空行":
                        removeFlag = False
                if zeroFill != "" and detailItem["column" + str(indexColumn)] is None:
                    detailValid[detailIndex]["column" + str(indexColumn)] = 0
            if removeFlag:
                removeFlag = False
                for indexColumn in range(indexStar, columnMax):
                    if str(detailItem["columnName" + str(indexColumn)]).strip() != "固定值":
                        removeFlag = True
                        break
            if removeFlag:
                detailRemove.append(detailItem)
        for detailItem in detailRemove:
            detailValid.remove(detailItem)
        if "sort" in content.keys():
            if content["sort"] == "id":
                detailValid.sort(key=lambda x: x["value"], reverse=False)
            elif content["sort"] == "-id":
                detailValid.sort(key=lambda x: x["value"], reverse=True)
            elif content["sort"] == "text":
                detailValid.sort(key=lambda x: x["text"], reverse=False)
            elif content["sort"] == "-text":
                detailValid.sort(key=lambda x: x["text"], reverse=True)
            elif content["sort"] == "textNum":
                detailValid.sort(key=lambda x: sort_key(x["textColumn"], False), reverse=False)
            elif content["sort"] == "-textNum":
                detailValid.sort(key=lambda x: sort_key(x["textColumn"], True), reverse=True)
            else:
                if str(content["sort"]).find(",请选择") > -1:content["sort"] = \
                    str(content["sort"]).replace(",请选择", "")
                if str(content["sort"]).find(",") > -1:
                    sortKey,sortWord = str(content["sort"]).split(','),False
                    if str(sortKey[0]).find("-") >= 0:sortWord = True
                    if sortKey[0].find('id') > -1 or sortKey[0].find('text') > -1:
                        sortKey[0] = str(sortKey[0]).replace("-", "")
                        if sortKey[0] == 'id': sortKey[0] = 'value'
                    else:
                        if rowText != "":
                            sortKey[0] = "column" + str(int(str(sortKey[0]).replace("-", "")) - 1)
                        else:
                            sortKey[0] = "column" + str(sortKey[0]).replace("-", "")
                    if sortKey[1].find('id') > -1 or sortKey[1].find('text')  > -1:
                        sortKey[1] = str(sortKey[1]).replace("-", "")
                        if sortKey[1] == 'id':sortKey[1] = 'value'
                    else:
                        if rowText != "":
                            sortKey[1] = "column" + str(int(str(sortKey[1]).replace("-", "")) - 1)
                        else:
                            sortKey[1] = "column" + str(sortKey[1]).replace("-", "")
                    if sortWord:
                        detailValid.sort(key=lambda x: (sort_key(x[str(sortKey[0])], True),
                                                        sort_key(x[str(sortKey[1])], True)), reverse=True)
                    else:
                        detailValid.sort(key=lambda x: (sort_key(x[str(sortKey[0])], False),
                                                        sort_key(x[str(sortKey[1])], False)), reverse=False)
                else:
                    if str(content["sort"]).find('id') > -1 or str(content["sort"]).find('text') > -1:
                        sortKey = str(content["sort"]).replace("-", "")
                        if sortKey == 'id': sortKey = 'value'
                    else:
                        if rowText != "":
                            sortKey = "column" + str(int(str(content["sort"]).replace("-", "")) - 1)
                        else:
                            sortKey = "column" + str(content["sort"]).replace("-", "")
                    if str(content["sort"]).find("-") >= 0:
                        detailValid.sort(key=lambda x: sort_key(x[str(sortKey)], True), reverse=True)
                    else:
                        detailValid.sort(key=lambda x: sort_key(x[str(sortKey)], False), reverse=False)
        else:
            if rowText != "":
                detailValid.sort(key=lambda x: x["value"], reverse=False)
        for detailIndex, detailItem in enumerate(detailValid):
            if str(detailItem["column0"]).strip() == "空行":
                for indexColumn in range(0, columnMax):
                    detailValid[detailIndex]["column" + str(indexColumn)] = ""
        if str(os.path.abspath(os.curdir)).find("core") > 0:
            filePath = os.path.abspath(os.curdir).replace("core", "docx")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
        chartJsonString, chartJsonPath, fromtext = dict(discription=[], chartall=[]), \
                                                   os.path.join(filePath, 'charts', chartJson), \
                                                   "[" + fromtext + position + "]"
        if position.find("图") > -1 : fromtext = position
        if os.path.exists(chartJsonPath):
            with open(chartJsonPath, "r", encoding="utf-8") as f:
                chartJsonString = json.load(f)
                f.close()
        if len(detailValid) > 0:
            if contentRow["type"] == "wordchart":
                rowStardef = lambda: "" if "rowStar" not in content.keys() else content["rowStar"]
                colStardef = lambda: "" if "colStar" not in content.keys() else content["colStar"]
                colEnddef = lambda: "" if "colEnd" not in content.keys() else content["colEnd"]
                tableResizedef = lambda: "" if "tableResize" not in content.keys() else content["tableResize"]
                colTitledef = lambda: "" if "colTitle" not in content.keys() else content["colTitle"]
                parameterdef = lambda: "" if "parameter" not in content.keys() else content["parameter"]
                chartHeightdef = lambda: "" if "chartHeight" not in content.keys() else content["chartHeight"]
                chartfiledef = lambda: "" if "chartfile" not in content.keys() else content["chartfile"]
                dataLabelColdef = lambda: "" if "dataLabelCol" not in content.keys() else content["dataLabelCol"]
                tableColdef = lambda: "" if "tableCol" not in content.keys() else content["tableCol"]
                colordef = lambda: "" if "color" not in content.keys() else content["color"]
                colorColdef = lambda: "" if "colorCol" not in content.keys() else content["colorCol"]
                rowStar, parameter, chartHeight, dataLabelCol, tableCol, color, colorCol, chartfile = \
                    rowStardef(), parameterdef(), chartHeightdef(), dataLabelColdef(), tableColdef(), \
                    colordef(), colorColdef(), chartfiledef()
                datasource, datasource2, datahead, wordChartJson, colStar, tableResize, colTitle, colEnd = \
                    [], [], [""], {}, colStardef(), tableResizedef(), colTitledef(), colEnddef()
                if isinstance(title, str):
                    if title == "":
                        if rowText != "":
                            dataColumnMax = columnMax
                        else:
                            dataColumnMax = columnMax - 1
                        for indexRow in range(dataColumnMax):
                            datahead.append(" ")
                    elif title != "delete":
                        datahead.append(title)
                else:
                    if isinstance(title, list):
                        if title[0].strip() == "":
                            datahead = []
                        for titleIndex in range(len(title)):
                            datahead.append(title[titleIndex])
                if len(datahead) > 1 : datasource.append(datahead)
                sumdata, sumName = [], []
                if displayRow != "" and len(detailValid) > int(displayRow) + 1:
                    for indexRow in range(0, columnMax):
                        sumdata.append(0)
                        sumName.append("")
                dataFlag2, textRow, indexStar, indexAdd, columnSplit = False, "text", 0, 1, False
                if rowText == "":
                    textRow, indexStar, indexAdd = "column0", 1, 0
                    if isinstance(title, list) and len(title) > columnMax : columnSplit = True
                else:
                    if isinstance(title, list) and len(title) - 1 > columnMax : columnSplit = True
                for detailIndex, detailItem in enumerate(detailValid):
                    if displayRow != "" and detailIndex >= int(displayRow) and len(detailValid) > int(displayRow) + 1:
                        if displayText == "":
                            if len(datasource)  - len(datasource2) < int(displayRow):
                                datadetail = [outputFormatData(detailItem[textRow],
                                                               detailItem[textRow.replace("column", "columnName")],
                                                               point, 0, unitsBefore,unitsAfter, replaceText, 0)]
                                for indexColumn in range(indexStar, columnMax):
                                    datadetail.append(outputFormatData(detailItem["column" + str(indexColumn)],
                                                                       detailItem["columnName" + str(indexColumn)],
                                                                       point, indexColumn + indexAdd, unitsBefore,
                                                                       unitsAfter, replaceText, 0))
                                datasource.append(datadetail)
                                if len(datasource2) > 0:
                                    del datasource2[0]
                            else:
                                break
                        else:
                            datadetail = [displayText]
                    else:
                        datadetail = [outputFormatData(detailItem[textRow],
                                                       detailItem[textRow.replace("column", "columnName")], point, 0 ,
                                                       unitsBefore, unitsAfter, replaceText, 0)]
                    if len(sortLast) > 0 and detailItem[textRow] in sortLast:
                        dataFlag2 = True
                    else:
                        if len(sortFirst) > 0:
                            if detailItem[textRow] in sortFirst:
                                dataFlag2 = False
                            else:
                                dataFlag2 = True
                        else:
                            dataFlag2 = False
                    if displayRow != "" and detailIndex >= int(displayRow) and len(detailValid) > int(displayRow) + 1:
                        for indexColumn in range(indexStar, columnMax):
                            if detailItem["columnName" + str(indexColumn)] == "固定值":
                                sumdata[indexColumn] = detailItem["column" + str(indexColumn)]
                            else:
                                sumdata[indexColumn] += detailItem["column" + str(indexColumn)]
                            sumName[indexColumn] = detailItem["columnName" + str(indexColumn)]
                    else:
                        for indexColumn in range(indexStar, columnMax):
                            datadetail.append(outputFormatData(detailItem["column" + str(indexColumn)],
                                                               detailItem["columnName" + str(indexColumn)], point,
                                                               indexColumn + indexAdd, unitsBefore,
                                                               unitsAfter, replaceText, 0))
                    if displayRow != "" and detailIndex >= int(displayRow) and len(detailValid) > int(displayRow) + 1:
                        if detailIndex == len(detailValid) - 1 and displayText != "":
                            for indexColumn in range(indexStar, columnMax):
                                if not columnSplit:
                                    datadetail.append(outputFormatData(str(sumdata[indexColumn]), sumName[indexColumn],
                                                      point,indexColumn + indexAdd, unitsBefore, unitsAfter,
                                                      replaceText, 0))
                                else:
                                    blankFlag = False
                                    for titleIndex in range(columnMax, len(title)):
                                        if str(title[titleIndex]).strip() == str(detailItem[textRow]).strip():
                                            blankFlag = True
                                    if blankFlag:
                                        datadetail.append("")
                                        for titleIndex in range(columnMax, len(title)):
                                            if str(title[titleIndex]).strip() == str(detailItem[textRow]).strip():
                                                datadetail.append(outputFormatData(str(sumdata[indexColumn]),
                                                                                   sumName[indexColumn], point,
                                                                                   indexColumn + indexAdd, unitsBefore,
                                                                                   unitsAfter, replaceText, 0))
                                            else:
                                                datadetail.append("")
                                    else:
                                        datadetail.append(outputFormatData(str(sumdata[indexColumn]),
                                                                           sumName[indexColumn],point,
                                                                           indexColumn + indexAdd, unitsBefore,
                                                                           unitsAfter, replaceText, 0))
                                        for titleIndex in range(columnMax, len(title)):
                                            datadetail.append("")
                            if dataFlag2:
                                datasource2.append(datadetail)
                            else:
                                datasource.append(datadetail)
                    else:
                        if dataFlag2:
                            datasource2.append(datadetail)
                        else:
                            datasource.append(datadetail)
                for detailItem in datasource2:
                    datasource.append(detailItem)
                chartfilePath, chartJsonPath, chartHeightValue,chartfileValue,deleteCol = \
                    "", os.path.join(filePath, 'charts', chartJson), "", "", []
                if isinstance(chartHeight, list):
                    if len(datasource) > int(chartHeight[1]):
                        chartHeightValue = chartHeight[2]
                    else:
                        chartHeightValue = chartHeight[0]
                if len(datasource) > 1 and len(datasource[0]) > 2 and len(datasource[0]) == len(datasource[1]) and \
                        title != "delete":
                    for colIndex in range(1, len(datasource[0])):
                        dataFlag = True
                        for rowIndex, rowItem in enumerate(datasource):
                            if rowIndex > 0 and str(rowItem[colIndex]).strip() != "":
                                dataFlag = False
                                break
                        if dataFlag:deleteCol.append(colIndex)
                    if len(deleteCol) > 0:datasource = np.delete(datasource, deleteCol, axis=1).tolist()
                if isinstance(chartfile, list):
                    if len(datasource) > int(chartfile[1]):
                        chartfileValue = os.path.join(filePath, 'charts', chartfile[2])
                        fromtextDel = chartfile[0]
                        fromtext = chartfile[2]
                    else:
                        chartfileValue = os.path.join(filePath, 'charts', chartfile[0])
                        if chartfile[0] == "chart-bys-bar1.docx":
                            if len(datasource[0]) >= 4:datasource = np.delete(datasource, [1, 3], axis=1).tolist()
                        fromtextDel = chartfile[2]
                    chartJsonString["chartall"].append(dict(fromtext=fromtextDel, chartHeight="", dataFlag="false",
                                                            chartfile="", datasource="", rowStar="",
                                                            colStar="", tableResize="", colTitle="",
                                                            parameter="", dataLabelCol="", tableCol="",
                                                            color="", colorCol="", chartLabelCol=chartLabelCol,
                                                            colEnd=""))
                    if not Path(chartfileValue).is_file():
                        chartfileValue = ""
                if colTitle == "delete":
                    datasource = np.delete(datasource, [0], axis=1).tolist()
                    colTitle = ""
                chartJsonString["chartall"].append(dict(fromtext=fromtext, chartHeight=chartHeightValue,dataFlag="true",
                                                        chartfile=chartfileValue, datasource=datasource,rowStar=rowStar,
                                                        colStar=colStar,tableResize=tableResize,colTitle=colTitle,
                                                        parameter=parameter,dataLabelCol=dataLabelCol,tableCol=tableCol,
                                                        color=color,colorCol=colorCol, chartLabelCol=chartLabelCol,
                                                        colEnd=colEnd, point=point))
                with open(chartJsonPath, "w", encoding="utf-8") as fp:
                    fp.write(json.dumps(chartJsonString, indent=4))
                    fp.close()
        else:
            chartJsonString["chartall"].append(dict(fromtext=fromtext, chartHeight="", dataFlag="false",
                                                    chartfile="", datasource="", rowStar="",
                                                    colStar="", tableResize="", colTitle="",
                                                    parameter="", dataLabelCol="", tableCol="",
                                                    color="", colorCol="", chartLabelCol=chartLabelCol,colEnd=""))
        with open(chartJsonPath, "w", encoding="utf-8") as fp:
            fp.write(json.dumps(chartJsonString, indent=4))
            fp.close()
    return None


def outDataProcess(outColumn, index, rowText, phrase, json_data, detailValid, rowIndex, discriptionFlag,
                   phraseData, point, rowPhrase, columnStringBack):
    if rowText == "textRow":
        optionId, optionText = "valueColumn", "textColumn"
    elif rowText == "textColumn":
        optionId, optionText = "valueRow", "textRow"
    else:
        optionId, optionText = "value", "text"
    if isinstance(rowPhrase, list):
        if len(rowPhrase) > rowIndex  > -1:
            phraseText = rowPhrase[rowIndex]
        else:
            phraseText = ""
    else:
        phraseText = ""
    columnString, textString, optionTextString, detailValidText, columnName, outValueName = \
        "column" + str(index), "", "", "text", "columnName" + str(index), "outValueText"
    detailValidPhrase, detailValidTextPhrase = "", ""
    if not discriptionFlag: point = ""
    if isinstance(outColumn, str) and str(outColumn).find("{}") > -1:
        outColumn, detailValidIndexStart = outColumn.split(';'), 0
        if isinstance(phrase, str) and str(phrase).strip() == "":
            detailValidIndexStart = len(detailValid) - 1
        for detailValidIndex in range(detailValidIndexStart, len(detailValid)):
            detailValidItem = detailValid[detailValidIndex]
            calculation, conversionValue, conversionFinal = myCalculation(), [], ""
            if phraseText != "" and "phrase" in detailValidItem.keys():detailValidPhrase = detailValidItem["phrase"]
            if "phrase" in detailValidItem.keys(): detailValidTextPhrase = detailValidItem["phrase"]
            for outColumnIndex, outColumnItem in enumerate(outColumn):
                if outColumnIndex > 0:
                    if outColumnItem.find(":") >= 0:
                        headFlag, dataValue, detailValidFlag,textString = False, 0.0, False, ""
                        outData = outColumnItem.split(':')
                        datasource = json.loads(json_data[outData[0].strip()])
                        head, detailValidFrom = datasource["head"][0], datasource["detailValid"]
                        if head["analysis"] == "means" : headFlag = True
                        if check_json_format(json.dumps(phrase)) and not isinstance(phrase, str):
                            if outData[0].strip() in phrase.keys(): textString = phrase[outData[0].strip()]
                        if outData[1].find("=") >= 0:
                            outValue = outData[1].strip().split('=')
                            outValueName = outValue[0].strip()
                            if discriptionFlag and columnString not in columnStringBack.keys():
                                if outValue[0].strip() == 'text' or outValue[0].strip() == 'value':
                                    columnStringBack[columnString] = \
                                        "option" + outValue[0].strip() + \
                                        returnColumnIndex(columnStringBack, "option" + outValue[0].strip())
                                else:
                                    columnStringBack[columnString] = \
                                        outValue[0].strip() + returnColumnIndex(columnStringBack, outValue[0].strip())
                        else:
                            outValue = outData[1].strip()
                            outValueName = outValue.strip()
                            if discriptionFlag and columnString not in columnStringBack.keys():
                                if outValue.strip() == 'text' or outValue.strip() == 'value':
                                    columnStringBack[columnString] = "option" + outValue.strip() + \
                                                                     returnColumnIndex(columnStringBack,
                                                                                       "option" + outValue.strip())
                                else:
                                    columnStringBack[columnString] = outValue.strip() + \
                                                                     returnColumnIndex(columnStringBack,outValue.strip())
                        if isinstance(outValue, list):
                            optionValue = outValue[1].split('&')
                            for optionValueIndex, optionValueItem in enumerate(optionValue):
                                if is_number(optionValueItem) and str(optionValueItem).find(".0") > 0:
                                    optionValue[optionValueIndex] = str(optionValueItem).replace(".0", "")
                            if (rowText == "" and textString == "") or (textString != "" and
                               (detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or
                                detailValidTextPhrase == textString)):
                                detailValidFlag = True
                            for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                                if head["analysis"] == "frequency" or head["analysis"] == "multiple":
                                    optionId, optionText = "value", "text"
                                elif head["analysis"] == "comparemeans" and rowText.strip() == "":
                                    optionId, optionText = "valueRow", "textRow"
                                else:
                                    if isinstance(detailValidFromItem[rowText], list):
                                        textString = ""
                                        for textItem in detailValidFromItem[rowText]:
                                            textString += str(textItem)
                                    else:
                                        textString = str(detailValidFromItem[rowText])
                                if (rowText == "" and textString == "") or \
                                        detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString \
                                        or detailValidTextPhrase == textString:
                                    detailValidFlag = True
                                    if isinstance(detailValidFromItem[optionText], list):
                                        optionTextString = ""
                                        for textItem in detailValidFromItem[optionText]:
                                            optionTextString += str(textItem)
                                    else:
                                        optionTextString = str(detailValidFromItem[optionText])
                                    for optionValueItem in optionValue:
                                        if str(optionValueItem).strip() == str(int(detailValidFromItem[optionId])) or \
                                                str(optionValueItem).strip() == optionTextString:
                                            dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                    outValue[0].strip(), discriptionFlag, point)
                        else:
                            if (rowText == "" and textString == "") or (textString != "" and
                               (detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or
                                detailValidTextPhrase == textString)):
                                detailValidFlag = True
                            if headFlag:
                                dataValue = outputData(head[outValue],outValue.strip(), discriptionFlag, point)
                            else:
                                for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                                    if rowText != "":
                                        if isinstance(detailValidFromItem[rowText], list):
                                            textString = ""
                                            for textItem in detailValidFromItem[rowText]:
                                                textString += str(textItem)
                                        else:
                                            textString = str(detailValidFromItem[rowText])
                                        if detailValidPhrase+detailValidItem[detailValidText] == phraseText+textString \
                                                or detailValidTextPhrase == textString:
                                            detailValidFlag = True
                                            dataValue += outputData(detailValidFromItem[outValue.strip()],
                                                                        outValue.strip(), discriptionFlag, point)
                                    else:
                                        dataValue += outputData(detailValidFromItem[outValue.strip()],
                                                                outValue.strip(), discriptionFlag, point)
                        if detailValidFlag:
                            conversionValue.append(str(dataValue))
                    else:
                        conversionValue.append(outColumnItem)
            if len(conversionValue) > 0 and len(conversionValue) == len(outColumn) - 1:
                conversionFinal = calculation.main(outColumn[0].format(*conversionValue))
                detailValid[detailValidIndex][columnString] = \
                    outputData(float(conversionFinal), "", discriptionFlag, point)
                if columnString in columnStringBack.keys():
                    detailValid[detailValidIndex][columnStringBack[columnString]] = \
                        detailValid[detailValidIndex][columnString]
            else:
                if columnString not in detailValid[detailValidIndex].keys():
                    detailValid[detailValidIndex][columnString] = None
                if discriptionFlag and columnString in columnStringBack.keys():
                    if columnStringBack[columnString] not in detailValid[detailValidIndex].keys():
                        detailValid[detailValidIndex][columnStringBack[columnString]] = None
            detailValid[detailValidIndex][columnName] = outValueName
            detailValid[detailValidIndex]["rowIndex"] = rowIndex
    elif str(outColumn).find(":") >= 0:
        outData = outColumn.split(':')
        datasource = json.loads(json_data[outData[0].strip()])
        if str(phraseData).strip() == str(outData[0].strip()).strip():detailValidText = "phrase"
        head, dataValueString, dataFalg = datasource["head"][0], "", False
        if outData[1].find("=") >= 0:
            outValue = outData[1].strip().split('=')
            outValueName = outValue[0].strip()
            if discriptionFlag and columnString not in columnStringBack.keys():
                if outValue[0].strip() == 'text' or outValue[0].strip() == 'value':
                    if outValue[1].strip() == "max" and outValue[0].strip() == 'text':
                        columnStringBack[columnString] = \
                            outValue[0].strip() + "max" + \
                            returnColumnIndex(columnStringBack, outValue[0].strip() + 'max')
                    else:
                        columnStringBack[columnString] = \
                            "option" + outValue[0].strip() + \
                            returnColumnIndex(columnStringBack, "option" + outValue[0].strip())
                else:
                    columnStringBack[columnString] = \
                        outValue[0].strip() + returnColumnIndex(columnStringBack, outValue[0].strip())
        else:
            outValue = outData[1].strip()
            outValueName = outValue
            if discriptionFlag and columnString not in columnStringBack.keys():
                if outValue.strip() == 'text' or outValue.strip() == 'value':
                    columnStringBack[columnString] = "option" + outValue.strip() + \
                                                     returnColumnIndex(columnStringBack,
                                                                       "option" + outValue.strip())
                else:
                    columnStringBack[columnString] = outValue.strip() + \
                                                     returnColumnIndex(columnStringBack, outValue.strip())
        if isinstance(outValue, list):
            optionValue, detailValidFrom = outValue[1].split('&'), datasource["detailValid"]
            for optionValueIndex, optionValueItem in enumerate(optionValue):
                if is_number(optionValueItem) and str(optionValueItem).find(".0") > 0:
                    optionValue[optionValueIndex] = str(optionValueItem).replace(".0", "")
            if outValue[1].strip() == "max":
                optionValue = "max"
            if head["analysis"] == "crosstabs":
                if rowText != "":
                    for detailValidIndex, detailValidItem in enumerate(detailValid):
                        if phraseText != "" and "phrase" in detailValidItem.keys():
                            detailValidPhrase = detailValidItem["phrase"]
                        if "phrase" in detailValidItem.keys():detailValidTextPhrase = detailValidItem["phrase"]
                        dataValue,dataValueMax,dataFalg = 0.0, 0.0, False
                        for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                            if isinstance(detailValidFromItem[rowText], list):
                                textString = ""
                                for textItem in detailValidFromItem[rowText]:
                                    textString += str(textItem)
                            else:
                                textString = str(detailValidFromItem[rowText])
                            if isinstance(detailValidFromItem[optionText], list):
                                optionTextString = ""
                                for textItem in detailValidFromItem[optionText]:
                                    optionTextString += str(textItem)
                            else:
                                optionTextString = str(detailValidFromItem[optionText])
                            if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or \
                                    detailValidTextPhrase == textString:
                                if isinstance(optionValue, str) and optionValue == "max":
                                    if detailValidFromItem["validpercent"] > dataValueMax:
                                        dataValueMax = detailValidFromItem["validpercent"]
                                        if str(outValue[0].strip()).find("text") >= 0:
                                            dataValueString = optionTextString
                                        else:
                                            dataValue = outputData(detailValidFromItem[outValue[0].strip()],
                                                                        outValue[0].strip(), discriptionFlag, point)
                                else:
                                    for optionValueItem in optionValue:
                                        if str(optionValueItem).strip() == str(int(detailValidFromItem[optionId])) or \
                                                str(optionValueItem).strip() == optionTextString:
                                            dataFalg = True
                                            if str(outValue[0].strip()).find("text") >= 0:
                                                if rowText.strip() == str(outValue[0].strip()).strip():
                                                    dataValueString = textString
                                                else:
                                                    dataValueString = dataValueString + optionTextString
                                            else:
                                                dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                        outValue[0].strip(), discriptionFlag, point)
                        if dataValueString != "":
                            detailValid[detailValidIndex][columnString] = dataValueString
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = dataValueString
                        else:
                            if dataFalg:
                                detailValid[detailValidIndex][columnString] = dataValue
                                if discriptionFlag and columnString in columnStringBack.keys()\
                                        :detailValid[detailValidIndex][columnStringBack[columnString]] = dataValue
                            else:
                                if columnString not in detailValid[detailValidIndex].keys():
                                    detailValid[detailValidIndex][columnString] = None
                                if discriptionFlag and columnString in columnStringBack.keys():
                                    if columnStringBack[columnString] not in detailValid[detailValidIndex].keys():
                                        detailValid[detailValidIndex][columnStringBack[columnString]] = None
                        detailValid[detailValidIndex]["rowIndex"] = rowIndex
                        detailValid[detailValidIndex][columnName] = outValueName
                else:
                    dataValue, dataValueMax = 0.0, 0.0
                    for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                        if isinstance(detailValidFromItem["textColumn"], list):
                            textString = ""
                            for textItem in detailValidFromItem["textColumn"]:
                                textString += str(textItem)
                        else:
                            textString = str(detailValidFromItem["textColumn"])
                        if isinstance(optionValue, str) and optionValue == "max":
                            if detailValidFromItem["validpercent"] > dataValueMax:
                                dataValueMax = detailValidFromItem["validpercent"]
                                if str(outValue[0].strip()).find("text") >= 0:
                                    dataValueString = textString
                                else:
                                    dataValue = outputData(detailValidFromItem[outValue[0].strip()],
                                                           outValue[0].strip(), discriptionFlag, point)
                        else:
                            for optionValueItem in optionValue:
                                if str(optionValueItem).strip() == str(int(detailValidFromItem["valueColumn"])) or \
                                        str(optionValueItem).strip() == textString:
                                    dataFalg = True
                                    if str(outValue[0].strip()).find("text") >= 0:
                                        if isinstance(detailValidFromItem[outValue[0].strip()], list):
                                            optionTextString = ""
                                            for textItem in detailValidFromItem[outValue[0].strip()]:
                                                optionTextString += str(textItem)
                                        else:
                                            optionTextString = str(detailValidFromItem[outValue[0].strip()])
                                        dataValueString = dataValueString + optionTextString
                                    else:
                                        dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                outValue[0].strip(), discriptionFlag, point)
                    if dataValueString != "":
                        detailValid[len(detailValid) - 1][columnString] = dataValueString
                        if discriptionFlag and columnString in columnStringBack.keys():
                            detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValueString
                    else:
                        if dataFalg:
                            detailValid[len(detailValid) - 1][columnString] = dataValue
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[len(detailValid) - 1].keys():
                                detailValid[len(detailValid) - 1][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys():
                                if columnStringBack[columnString] not in detailValid[len(detailValid) - 1].keys():
                                    detailValid[len(detailValid) - 1][columnStringBack[columnString]] = None
                    detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                    detailValid[len(detailValid) - 1][columnName] = outValueName
            else:
                if rowText != "":
                    for detailValidIndex, detailValidItem in enumerate(detailValid):
                        dataValue, dataValueMax = 0.0, 0.0
                        if phraseText != "" and "phrase" in detailValidItem.keys():
                            detailValidPhrase = detailValidItem["phrase"]
                        if "phrase" in detailValidItem.keys(): detailValidTextPhrase = detailValidItem["phrase"]
                        for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                            if isinstance(detailValidFromItem["text"], list):
                                textString = ""
                                for textItem in detailValidFromItem["text"]:
                                    textString += str(textItem)
                            else:
                                textString = str(detailValidFromItem["text"])
                            dataFalg = True
                            if rowText == "textRow":
                                if detailValidPhrase + detailValidItem[detailValidText] == \
                                        phraseText + phrase[outData[0].strip()] or \
                                        detailValidTextPhrase == phrase[outData[0].strip()]:
                                    if isinstance(optionValue, str) and optionValue == "max":
                                        if detailValidFromItem["validpercent"] > dataValueMax:
                                            dataValueMax = detailValidFromItem["validpercent"]
                                            if str(outValue[0].strip()).find("text") >= 0:
                                                dataValueString = textString
                                            else:
                                                dataValue = outputData(detailValidFromItem[outValue[0].strip()],
                                                                       outValue[0].strip(), discriptionFlag, point)
                                    else:
                                        for optionValueItem in optionValue:
                                            if str(optionValueItem).strip() == str(int(detailValidFromItem["value"])) \
                                                    or str(optionValueItem).strip() == textString:
                                                if str(outValue[0].strip()).find("text") >= 0:
                                                    if isinstance(detailValidFromItem[outValue[0].strip()], list):
                                                        optionTextString = ""
                                                        for textItem in detailValidFromItem[outValue[0].strip()]:
                                                            optionTextString += str(textItem)
                                                    else:
                                                        optionTextString = str(detailValidFromItem[outValue[0].strip()])
                                                    dataValueString = dataValueString + optionTextString
                                                else:
                                                    dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                        outValue[0].strip(), discriptionFlag, point)
                                else:
                                    dataFalg = False
                            else:
                                if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or \
                                        detailValidTextPhrase == textString:
                                    dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                            outValue[0].strip(), discriptionFlag, point)
                        if dataFalg:
                            if dataValueString != "":
                                detailValid[detailValidIndex][columnString] = dataValueString
                                if discriptionFlag and columnString in columnStringBack.keys():
                                    detailValid[detailValidIndex][columnStringBack[columnString]] = dataValueString
                            else:
                                detailValid[detailValidIndex][columnString] = dataValue
                                if discriptionFlag and columnString in columnStringBack.keys():
                                    detailValid[detailValidIndex][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys() and \
                                    columnStringBack[columnString] not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = None
                        detailValid[detailValidIndex]["rowIndex"] = rowIndex
                        detailValid[detailValidIndex][columnName] = outValueName
                else:
                    dataValue, dataValueMax = 0.0, 0.0
                    if head["analysis"] == "comparemeans":
                        for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                            if isinstance(detailValidFromItem["textRow"], list):
                                textString = ""
                                for textItem in detailValidFromItem["textRow"]:
                                    textString += str(textItem)
                            else:
                                textString = str(detailValidFromItem["textRow"])
                            if isinstance(optionValue, str) and optionValue == "max":
                                if detailValidFromItem["validpercent"] > dataValue:
                                    dataValue = detailValidFromItem["average"]
                            else:
                                for optionValueItem in optionValue:
                                    if str(optionValueItem).strip() == str(int(detailValidFromItem["valueRow"])) or \
                                            str(optionValueItem).strip() == textString:
                                        dataFalg = True
                                        dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                outValue[0].strip(),  discriptionFlag, point)
                    else:
                        dataValueStringGroup = []
                        for optionIndex in range(len(optionValue)):
                            dataValueStringGroup.append("")
                        for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                            if isinstance(detailValidFromItem["text"], list):
                                textString = ""
                                for textItem in detailValidFromItem["text"]:
                                    textString += str(textItem)
                            else:
                                textString = str(detailValidFromItem["text"])
                            if isinstance(optionValue, str) and optionValue == "max":
                                if detailValidFromItem["count"] > dataValueMax:
                                    dataValueMax = detailValidFromItem["count"]
                                    if str(outValue[0].strip()).find("text") >= 0:
                                        dataValueString = textString
                                    else:
                                        dataValue = outputData(detailValidFromItem[outValue[0].strip()],
                                                               outValue[0].strip(), discriptionFlag, point)
                            else:
                                for optionValueIndex, optionValueItem in enumerate(optionValue):
                                    if str(optionValueItem).strip() == str(int(detailValidFromItem["value"])) or \
                                            str(optionValueItem).strip() == textString:
                                        dataFalg = True
                                        if str(outValue[0].strip()).find("text") >= 0:
                                            if isinstance(detailValidFromItem[outValue[0].strip()], list):
                                                optionTextString = ""
                                                for textItem in detailValidFromItem[outValue[0].strip()]:
                                                    optionTextString += str(textItem)
                                            else:
                                                optionTextString = str(detailValidFromItem[outValue[0].strip()])
                                            dataValueStringGroup[optionValueIndex] = optionTextString
                                        else:
                                            dataValue += outputData(detailValidFromItem[outValue[0].strip()],
                                                                    outValue[0].strip(), discriptionFlag, point)
                        for dataValueStringGroupItem in dataValueStringGroup:
                            dataValueString += dataValueStringGroupItem
                    if dataValueString != "":
                        detailValid[len(detailValid) - 1][columnString] = dataValueString
                        if discriptionFlag and columnString in columnStringBack.keys():
                            detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValueString
                    else:
                        if dataFalg:
                            detailValid[len(detailValid) - 1][columnString] = dataValue
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[len(detailValid) - 1].keys():
                                detailValid[len(detailValid) - 1][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys() and \
                                    columnStringBack[columnString] not in detailValid[len(detailValid) - 1].keys():
                                detailValid[len(detailValid) - 1][columnStringBack[columnString]] = None
                    detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                    detailValid[len(detailValid) - 1][columnName] = outValueName
        else:
            if head["analysis"] == "means":
                if rowText != "":
                    for detailValidIndex, detailValidItem in enumerate(detailValid):
                        if phraseText != "" and "phrase" in detailValidItem.keys():
                            detailValidPhrase = detailValidItem["phrase"]
                        if "phrase" in detailValidItem.keys(): detailValidTextPhrase = detailValidItem["phrase"]
                        dataValue, dataFalg = 0.0, False
                        if isinstance(phrase, str) and phrase == "":
                            detailValidFrom = datasource["detailValid"]
                            for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                                if isinstance(detailValidFromItem["text"], list):
                                    textString = ""
                                    for textItem in detailValidFromItem["text"]:
                                        textString += str(textItem)
                                else:
                                    textString = str(detailValidFromItem["text"])
                                if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or \
                                        detailValidTextPhrase == textString:
                                    dataFalg, dataValue = True, outputData(detailValidFromItem[outValue], outValue,
                                                                           discriptionFlag, point)
                                    break
                        else:
                            for keyPhrase, valuePhrase in phrase.items():
                                if (detailValidPhrase + detailValidItem[detailValidText] == phraseText + valuePhrase or
                                    detailValidTextPhrase == valuePhrase) and outData[0] == keyPhrase:
                                    dataFalg, dataValue = True, outputData(head[outValue], outValue, discriptionFlag,
                                                                           point)
                        if dataFalg:
                            detailValid[detailValidIndex][columnString] = dataValue
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys() and \
                                    columnStringBack[columnString] not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = None
                        detailValid[detailValidIndex]["rowIndex"] = rowIndex
                        detailValid[detailValidIndex][columnName] = outValueName
                else:
                    detailValid[len(detailValid) - 1][columnString] = outputData(head[outValue], outValue,
                                                                                 discriptionFlag, point)
                    if discriptionFlag and columnString in columnStringBack.keys():
                        detailValid[len(detailValid) - 1][columnStringBack[columnString]] = \
                        outputData(head[outValue], outValue,discriptionFlag, point)
                    detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                    detailValid[len(detailValid) - 1][columnName] = outValueName
            else:
                detailValidFrom = datasource["detailValid"]
                if rowText != "":
                    for detailValidIndex, detailValidItem in enumerate(detailValid):
                        if phraseText != "" and "phrase" in detailValidItem.keys():
                            detailValidPhrase = detailValidItem["phrase"]
                        if "phrase" in detailValidItem.keys(): detailValidTextPhrase = detailValidItem["phrase"]
                        dataValue,dataFalg = 0.0, False
                        for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                            if head["analysis"] == "comparemeans":
                                if isinstance(detailValidFromItem["textRow"], list):
                                    textString = ""
                                    for textItem in detailValidFromItem["textRow"]:
                                        textString += str(textItem)
                                else:
                                    textString = str(detailValidFromItem["textRow"])
                                if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or\
                                        detailValidTextPhrase == textString:
                                    dataFalg = True
                                    if str(outValue.strip()).find("text") >= 0:
                                        dataValue = str(detailValidFromItem[outValue]).strip()
                                    else:
                                        dataValue += outputData(detailValidFromItem[outValue], outValue,
                                                                discriptionFlag, point)
                            elif head["analysis"] == "crosstabs":
                                if isinstance(detailValidFromItem[rowText], list):
                                    textString = ""
                                    for textItem in detailValidFromItem[rowText]:
                                        textString += str(textItem)
                                else:
                                    textString = str(detailValidFromItem[rowText])
                                if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or\
                                        detailValidTextPhrase == textString:
                                    dataFalg = True
                                    if str(outValue.strip()).find("text") >= 0:
                                        dataValue = str(detailValidFromItem[outValue]).strip()
                                    else:
                                        dataValue += outputData(detailValidFromItem[outValue], outValue,discriptionFlag,
                                                                point)
                            else:
                                if isinstance(detailValidFromItem["text"], list):
                                    textString = ""
                                    for textItem in detailValidFromItem["text"]:
                                        textString += str(textItem)
                                else:
                                    textString = str(detailValidFromItem["text"])
                                if detailValidPhrase + detailValidItem[detailValidText] == phraseText + textString or\
                                        detailValidTextPhrase == textString:
                                    dataFalg = True
                                    dataValue += outputData(detailValidFromItem[outValue], outValue, discriptionFlag,
                                                            point)
                        if dataFalg:
                            detailValid[detailValidIndex][columnString] = dataValue
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys() and \
                                    columnStringBack[columnString] not in detailValid[detailValidIndex].keys():
                                detailValid[detailValidIndex][columnStringBack[columnString]] = None
                        detailValid[detailValidIndex]["rowIndex"] = rowIndex
                        detailValid[detailValidIndex][columnName] = outValueName
                else:
                    dataValue = 0.0
                    for detailValidFromIndex, detailValidFromItem in enumerate(detailValidFrom):
                        dataFalg = True
                        if str(outValue).find("text") >= 0:
                            if isinstance(detailValidFromItem[outValue], list):
                                textString = ""
                                for textItem in detailValidFromItem[outValue]:
                                    textString += str(textItem)
                            else:
                                textString = str(detailValidFromItem[outValue])
                            dataValueString = dataValueString + textString
                        else:
                            dataValue += outputData(detailValidFromItem[outValue], outValue, discriptionFlag,
                                                    point)
                    if dataValueString != "":
                        detailValid[len(detailValid) - 1][columnString] = dataValueString
                        if discriptionFlag and columnString in columnStringBack.keys():
                            detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValueString
                    else:
                        if dataFalg:
                            detailValid[len(detailValid) - 1][columnString] = dataValue
                            if discriptionFlag and columnString in columnStringBack.keys():
                                detailValid[len(detailValid) - 1][columnStringBack[columnString]] = dataValue
                        else:
                            if columnString not in detailValid[len(detailValid) - 1].keys():
                                detailValid[len(detailValid) - 1][columnString] = None
                            if discriptionFlag and columnString in columnStringBack.keys() and\
                                    columnStringBack[columnString] not in detailValid[len(detailValid) - 1].keys():
                                detailValid[len(detailValid) - 1][columnStringBack[columnString]] = None
                    detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                    detailValid[len(detailValid) - 1][columnName] = outValueName
    else:
        if outColumn.find("data") >= 0 and outColumn.find("/") >= 0:
            if outColumn.find(",") >= 0:
                detailValid[len(detailValid) - 1][columnString] = passRate(outColumn, json_data)
                detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                detailValid[len(detailValid) - 1][columnName] = outValueName
        else:
            outValueName = '固定值'
            if rowText != "":
                for detailValidIndex, detailValidItem in enumerate(detailValid):
                    setFlag = True
                    if index > 0:
                        setFlag = False
                        for cnt in range(index):
                            if "column" + str(cnt) in detailValid[detailValidIndex]:
                                if detailValid[detailValidIndex]["column" + str(cnt)] is not None:
                                    setFlag = True
                            else:
                                setFlag = True
                    if columnString not in detailValid[detailValidIndex] or \
                        detailValid[detailValidIndex][columnString] is None:
                        if setFlag:
                            detailValid[detailValidIndex][columnString] = outColumn
                        else:
                            detailValid[detailValidIndex][columnString] = None
                    detailValid[detailValidIndex]["rowIndex"] = rowIndex
                    detailValid[detailValidIndex][columnName] = outValueName
            else:
                if discriptionFlag and "text" not in detailValid[len(detailValid) - 1].keys(): columnString = "text"
                setFlag = True
                if index > 1:
                    setFlag = False
                    for cnt in range(1,index):
                        if "column" + str(cnt) in detailValid[len(detailValid) - 1]:
                            if detailValid[len(detailValid) - 1]["column" + str(cnt)] is not None:
                                setFlag = True
                        else:
                            setFlag = True
                if setFlag:
                    detailValid[len(detailValid) - 1][columnString] = outColumn
                else:
                    detailValid[len(detailValid) - 1][columnString] = None
                detailValid[len(detailValid) - 1]["rowIndex"] = rowIndex
                detailValid[len(detailValid) - 1][columnName] = outValueName
    return detailValid


def rowDataProcess(outColumn, rowText, phrase, rowPhrase, rowNo, sortAll, json_data, discriptionFlag,phraseData, point):
    phraseSave, dataSave, text, valueColumn, phraseBreak, columnMax, detailValid, detailValidTotal, textString = \
        [], [], [], "", "", 0, [], [], ""
    if rowText == "textRow":
        valueColumn = "valueRow"
    elif rowText == "textColumn":
        valueColumn = "valueColumn"
    else:
        valueColumn = "value"
    if True == isinstance(rowPhrase, str) and rowPhrase.find("data") > -1 and rowPhrase.find(":") > -1:
        if rowPhrase.find(";") > -1 :
            rowOutDataAll = rowPhrase.split(';')
            rowOutData, rowOutDataCount = rowOutDataAll[0].split(':'), len(rowOutDataAll)
        else:
            rowOutDataAll, rowOutDataCount = None, 1
            rowOutData = rowPhrase.split(':')
        outText, datasource = rowOutData[1].split(','), json.loads(json_data[rowOutData[0]])
        detailValidFrom, headPhrase, rowPhrase, colPhrase, rowId, columnId, rowIndex, columnIndex = \
            datasource["detailValid"], [], [], [], "", "", 0, 0
        for indexColumn in range(len(outColumn)):
            if isinstance(outColumn[indexColumn], list):
                if len(outColumn[indexColumn]) > columnMax: columnMax = len(outColumn[indexColumn])
            else:
                if len(outColumn) > columnMax: columnMax = len(outColumn)
        if len(outText) > 0:
            for dataItem in detailValidFrom:
                if isinstance(dataItem[outText[0]], list):
                    textString = ""
                    for textItem in dataItem[outText[0]]:
                        textString += str(textItem)
                else:
                    textString = str(dataItem[outText[0]])
                if textString not in rowPhrase:rowPhrase.append(textString)
            for rowPhraseItem in rowPhrase:
                colText = []
                for dataItem in detailValidFrom:
                    if isinstance(dataItem[outText[0]], list):
                        textString = ""
                        for textItem in dataItem[outText[0]]:
                            textString += str(textItem)
                    else:
                        textString = str(dataItem[outText[0]])
                    if rowPhraseItem == textString:
                        if isinstance(dataItem[outText[1]], list):
                            textString = ""
                            for textItem in dataItem[outText[1]]:
                                textString += str(textItem)
                        else:
                            textString = str(dataItem[outText[1]])
                        if textString not in colText: colText.append(textString)
                colPhrase.append(colText)
        if isinstance(rowOutDataAll, list):
            headPhrase, rowPhrase, colPhrase = copy.deepcopy(rowPhrase), copy.deepcopy(colPhrase), []
            rowOutData = rowOutDataAll[1].split(':')
            outText, datasource = rowOutData[1].split(','), json.loads(json_data[rowOutData[0]])
            detailValidFrom = datasource["detailValid"]
            if len(outText) > 0:
                for rowPhraseItem in rowPhrase:
                    colText = []
                    for rowPhraseColItem in rowPhraseItem:
                        colItemText = []
                        for dataItem in detailValidFrom:
                            if isinstance(dataItem[outText[0]], list):
                                textString = ""
                                for textItem in dataItem[outText[0]]:
                                    textString += str(textItem)
                            else:
                                textString = str(dataItem[outText[0]])
                            if rowPhraseColItem == textString:
                                if isinstance(dataItem[outText[1]], list):
                                    textString = ""
                                    for textItem in dataItem[outText[1]]:
                                        textString += str(textItem)
                                else:
                                    textString = str(dataItem[outText[1]])
                                if textString not in colItemText: colItemText.append(textString)
                        colText.append(colItemText)
                    colPhrase.append(colText)
        if len(detailValidTotal) == 0:
            phraseSave, indexPhrase = rowPhrase, 0
            if len(headPhrase) > 0:
                for headPhraseIndex, headPhraseItem in enumerate(headPhrase):
                    for rowPhraseIndex, rowPhraseItem in enumerate(rowPhrase[headPhraseIndex]):
                        for colPhraseIndex, colPhraseItem in enumerate(colPhrase[headPhraseIndex][rowPhraseIndex]):
                            detailValid.append(dict(value=indexPhrase + 1, text=colPhraseItem, phrase=rowPhraseItem,
                                                    headPhrase=headPhraseItem,columnMax=columnMax))
                            indexPhrase += 1
            else:
                for rowPhraseIndex, rowPhraseItem in enumerate(rowPhrase):
                    for colPhraseIndex, colPhraseItem in enumerate(colPhrase[rowPhraseIndex]):
                        detailValid.append(dict(value=indexPhrase + 1, text=colPhraseItem, phrase=rowPhraseItem,
                                                columnMax=columnMax))
                        indexPhrase += 1
            detailValidTotal.append(copy.deepcopy(detailValid))
            detailValid.clear()
            if isinstance(outColumn[0], list):
                if check_json_format(json.dumps(phrase)):
                    for indexColumn in range(1, len(outColumn)):
                        for columnItem in outColumn[indexColumn]:
                            if columnItem.find(":") > -1:
                                outData = columnItem.split(':')
                                for key, value in phrase.items():
                                    if str(outData[0]) == str(key):
                                        if str(value) not in text:
                                            for sortIndex, sortItem in enumerate(sortAll):
                                                if str(value) == sortItem:
                                                    if rowNo > 0:
                                                        rowNo -= sortIndex
                                                    else:
                                                        rowNo += sortIndex
                                            text.append(str(value))
                                            if len(headPhrase) > 0:
                                                detailValid.append(dict(value=rowNo, text=str(value), phrase="",
                                                                        headPhrase="", columnMax=columnMax))
                                            else:
                                                detailValid.append(dict(value=rowNo, text=str(value), phrase="",
                                                                        columnMax=columnMax))
                if len(detailValid) > 0:
                    detailValidTotal.append(copy.deepcopy(detailValid))
                    detailValid.clear()
    else:
        for index in range(len(outColumn)):
            if isinstance(outColumn[index], list):
                if len(outColumn[index]) > columnMax: columnMax = len(outColumn[index])
                for indexCol in range(len(outColumn[index])):
                    if outColumn[index][indexCol].find(":") >= 0:
                        if outColumn[index][indexCol].find("{}") > -1:
                            outColumnItem,outData = outColumn[index][indexCol].split(';'), ['']
                            for outColumnData in outColumnItem:
                                if outColumnData.find(":") >= 0:
                                    outData = outColumnData.split(':')
                                    break
                        else:
                            outData = outColumn[index][indexCol].split(':')
                        if isinstance(rowPhrase, list) and index < len(rowPhrase) and \
                                (outData[0] not in dataSave or rowPhrase[index] not in phraseSave):
                            dataSave.append(outData[0]), phraseSave.append(rowPhrase[index])
                        else:
                            if outData[0] not in dataSave:
                                dataSave.append(outData[0])
            else:
                if len(outColumn) > columnMax: columnMax = len(outColumn)
                if outColumn[index].find(":") >= 0:
                    if outColumn[index].find("{}") > -1:
                        outColumnItem, outData = outColumn[index].split(';'), ['']
                        for outColumnData in outColumnItem:
                            if outColumnData.find(":") >= 0:
                                outData = outColumnData.split(':')
                                outData[0] = outData[0].replace('head', '')
                                break
                    else:
                        outData = outColumn[index].split(':')
                    if isinstance(rowPhrase, list) and index < len(rowPhrase) and \
                            (outData[0] not in dataSave or rowPhrase[index] not in phraseSave):
                        dataSave.append(outData[0]), phraseSave.append(rowPhrase[index])
                    else:
                        if outData[0] not in dataSave:
                            dataSave.append(outData[0])
                            if isinstance(outColumn[0], str) and isinstance(rowPhrase, list):
                                phraseSave.append(rowPhrase[0])
        if len(phraseSave) > 0: phraseBreak = phraseSave[0]
        for dataSaveIndex, dataSaveItem in enumerate(dataSave):
            datasource = json.loads(json_data[dataSaveItem])
            head = datasource["head"][0]
            if rowText == "textRow":
                if head["analysis"] == "crosstabs" or head["analysis"] == "comparemeans":
                    detailValidFrom = datasource["detailValid"]
                    for dataItem in detailValidFrom:
                        if isinstance(dataItem[rowText], list):
                            textString = ""
                            for textItem in dataItem[rowText]:
                                textString += str(textItem)
                        else:
                            textString = str(dataItem[rowText])
                        if textString not in text:
                            text.append(textString)
                            if len(phraseSave) > 0:
                                detailValid.append(dict(value=dataItem[valueColumn], text=textString, data=dataSaveItem,
                                                        phrase=phraseSave[dataSaveIndex], columnMax=columnMax))
                            else:
                                detailValid.append(dict(value=dataItem[valueColumn], text=textString,
                                                        data=dataSaveItem, columnMax=columnMax))
                else:
                    if check_json_format(json.dumps(phrase)):
                        for key, value in phrase.items():
                            if str(dataSaveItem) == str(key):
                                if str(value) not in text:
                                    for sortIndex, sortItem in enumerate(sortAll):
                                        if str(value) == sortItem:
                                            if rowNo > 0:
                                                rowNo -= sortIndex
                                            else:
                                                rowNo += sortIndex
                                    text.append(str(value))
                                    if len(phraseSave) > 0:
                                        detailValid.append(dict(value=rowNo, text=str(value),data=dataSaveItem,
                                                                phrase=phraseSave[dataSaveIndex], columnMax=columnMax))
                                    else:
                                        detailValid.append(dict(value=rowNo, text=str(value),data=dataSaveItem,
                                                                columnMax=columnMax))
            else:
                if head["analysis"] == "crosstabs":
                    detailValidFrom = datasource["detailValid"]
                    for dataItem in detailValidFrom:
                        if isinstance(dataItem[rowText], list):
                            textString = ""
                            for textItem in dataItem[rowText]:
                                textString += str(textItem)
                        else:
                            textString = str(dataItem[rowText])
                        if textString not in text:
                            text.append(textString)
                            if len(phraseSave) > 0:
                                detailValid.append(
                                    dict(value=dataItem[valueColumn], text=textString, data=dataSaveItem,
                                         phrase=phraseSave[dataSaveIndex], columnMax=columnMax))
                            else:
                                detailValid.append(
                                    dict(value=dataItem[valueColumn], text=textString, data=dataSaveItem,
                                         columnMax=columnMax))
                elif head["analysis"] == "means" and check_json_format(json.dumps(phrase)):
                    for key, value in phrase.items():
                        if str(dataSaveItem) == str(key):
                            if str(value) not in text:
                                text.append(str(value))
                                for sortIndex, sortItem in enumerate(sortAll):
                                    if str(key) == sortItem:
                                        if rowNo > 0:
                                            rowNo -= sortIndex
                                        else:
                                            rowNo += sortIndex
                                if len(phraseSave) > 0:
                                    detailValid.append(dict(value=rowNo, text=str(value), data=dataSaveItem,
                                                            phrase=phraseSave[dataSaveIndex],columnMax=columnMax))
                                else:
                                    detailValid.append(dict(value=rowNo, text=str(value), data=dataSaveItem,
                                                            columnMax=columnMax))
                else:
                    detailValidFrom = datasource["detailValid"]
                    if rowText == "textColumn" or rowText == "text":
                        for dataItem in detailValidFrom:
                            if isinstance(dataItem["text"], list):
                                textString = ""
                                for textItem in dataItem["text"]:
                                    textString += str(textItem)
                            else:
                                textString = str(dataItem["text"])
                            if textString not in text:
                                text.append(textString)
                                if len(phraseSave) > 0:
                                    detailValid.append(dict(value=dataItem["value"], text=textString, data=dataSaveItem,
                                                            phrase=phraseSave[dataSaveIndex], columnMax=columnMax))
                                else:
                                    detailValid.append(dict(value=dataItem["value"], text=textString,
                                                            data=dataSaveItem, columnMax=columnMax))
                    else:
                        for dataItem in detailValidFrom:
                            if isinstance(dataItem[rowText], list):
                                textString = ""
                                for textItem in dataItem[rowText]:
                                    textString += str(textItem)
                            else:
                                textString = str(dataItem[rowText])
                            if textString not in text:
                                text.append(textString)
                                if len(phraseSave) > 0:
                                    detailValid.append(
                                        dict(value=dataItem[valueColumn], text=textString, data=dataSaveItem,
                                             phrase=phraseSave[dataSaveIndex], columnMax=columnMax))
                                else:
                                    detailValid.append(
                                        dict(value=dataItem[valueColumn], text=textString, data=dataSaveItem,
                                             columnMax=columnMax))
            if len(phraseSave) > 0 and (dataSaveIndex == len(dataSave) - 1 or
                                        phraseBreak != phraseSave[dataSaveIndex + 1]):
                detailValidTotal.append(copy.deepcopy(detailValid))
                detailValid.clear(), text.clear()
            if len(phraseSave) > dataSaveIndex + 1: phraseBreak = phraseSave[dataSaveIndex + 1]
    columnStringBack = {}
    if len(phraseSave) > 0:
        for indexRow in range(len(outColumn)):
            if isinstance(outColumn[indexRow], list):
                detailValidTotalItem = detailValidTotal[indexRow]
                for indexCol in range(len(outColumn[indexRow])):
                    detailValidTotal[indexRow] = \
                        outDataProcess(outColumn[indexRow][indexCol], indexCol, rowText, phrase, json_data,
                                       detailValidTotalItem, indexRow, discriptionFlag, phraseData, point,
                                       rowPhrase, columnStringBack)
            else:
                detailValidTotal[0] = outDataProcess(outColumn[indexRow], indexRow, rowText, phrase, json_data,
                                                     detailValidTotal[0], -1, discriptionFlag, phraseData, point,
                                                     rowPhrase, columnStringBack)
    else:
        for indexRow in range(len(outColumn)):
            if isinstance(outColumn[indexRow], list):
                for indexCol in range(len(outColumn[indexRow])):
                    detailValid = outDataProcess(outColumn[indexRow][indexCol], indexCol, rowText, phrase, json_data,
                                                 detailValid, indexRow, discriptionFlag, phraseData, point,
                                                 rowPhrase, columnStringBack)
            else:
                detailValid = outDataProcess(outColumn[indexRow], indexRow, rowText, phrase, json_data, detailValid, -1,
                                             discriptionFlag, phraseData, point, rowPhrase, columnStringBack)
        detailValidTotal.append(detailValid)
    return detailValidTotal


def returnColumnIndex(columnJson, columnString):
    columnIndex = ''
    if columnJson:
        for columnKey in columnJson.keys():
            if str(columnJson[columnKey]).find(columnString) > -1:
                columnIndexBack = str(columnJson[columnKey]).replace('columnString', '')
                if columnIndexBack == '':columnIndexBack = "1"
                if columnIndex == '':
                    columnIndex = columnIndexBack
                else:
                    if int(columnIndex) <= int(columnIndexBack):
                        columnIndex = str(int(columnIndexBack) + 1)
        return columnIndex
    else:
        return columnIndex


def outputData(outValue, outColumn, discriptionFlag, point):
    if outColumn == "validP" or outColumn == "missingP" or outColumn == "validpercent" or outColumn == "percent" \
            or outColumn == "invalidP" or outColumn == "casepercent" or outColumn == "passRate" or \
            outColumn == "masteryRate" or outColumn == "masteryRateAll" or outColumn == "percentileRank" :
        if point == "":
            if not discriptionFlag:
                return outValue * 100
            else:
                return outValue
        else:
            if not discriptionFlag:
                return float(str(formatdata(outValue * 100, int(point))))
            else:
                return float(str(formatdata(outValue, int(point) + 2)))
    elif outColumn == "average" or outColumn == "max" or outColumn == "median" or outColumn == "stdev" or \
            outColumn == "variance" or outColumn == "Percent5" or outColumn == "Percent10" or \
            outColumn == "Percent25" or outColumn == "Percent75" or outColumn == "Percent90" or outColumn == "Percent95":
        if point == "" or outValue == "":
            return outValue
        else:
            return float(str(formatdata(outValue, int(point))))
    elif outColumn == "count":
        return int(outValue)
    else:
        return outValue


def outputFormatData(outValue, columnName, point, indexColumn, unitsBefore, unitsAfter, replaceText, rowIndex):
    if outValue is None:
        outFormatData = ""
    elif outValue == "index":
        outFormatData = str(rowIndex)
    elif isinstance(outValue, str) and outValue.strip() == "":
        outFormatData = ""
    else:
        pointInt = 2
        if isinstance(outValue, float) or isinstance(outValue, int):
            if isinstance(point, list) and len(point) > 0:
                if point[0] is None:
                    outFormatData = formatdata(outValue, pointInt)
                else:
                    if len(point) > indexColumn:
                        if point[indexColumn] != "" : pointInt = point[indexColumn]
                    else:
                        if point[len(point) - 1] != "": pointInt = point[len(point) - 1]
                    outFormatData = formatdata(outValue, pointInt)
            else:
                if columnName == "validP" or columnName == "missingP" or columnName == "validpercent" or \
                        columnName == "percent" or columnName == "invalidP" or columnName == "casepercent" or \
                        columnName == "passRate" or columnName == "masteryRate" or columnName == "masteryRateAll" or \
                        columnName == "percentileRank" or columnName == "average" or columnName == "max" or \
                        columnName == "min" or columnName == "median" or columnName == "stdev" or \
                        columnName == "variance" or str(columnName).find("Percent") > -1 or columnName == "sum" or \
                        columnName == "mode":
                    if check_json_format(json.dumps(point)):
                        if "point" in point.keys() : pointInt = point["point"]
                        if columnName in point.keys(): pointInt = point[columnName]
                        outFormatData = formatdata(outValue, pointInt)
                    else:
                        outFormatData = formatdata(outValue, point)
                elif columnName == "count" or columnName == "sort":
                    outFormatData = str(int(outValue))
                else:
                    outFormatData = str(outValue)
        else:
            outFormatData = str(outValue)

        if isinstance(unitsAfter, list) and len(unitsAfter) > 0:
            if len(unitsAfter) > indexColumn and unitsAfter[0] is not None:
                outFormatData = outFormatData + unitsAfter[indexColumn]
        elif check_json_format(json.dumps(unitsAfter)):
            if columnName in unitsAfter.keys(): outFormatData = outFormatData + unitsAfter[columnName]
        else:
            if is_number(outValue):outFormatData = outFormatData + unitsAfter
        if isinstance(unitsBefore, list) and len(unitsBefore) > 0:
            if len(unitsBefore) > indexColumn and unitsBefore[0] is not None:
                outFormatData = unitsBefore[indexColumn] + outFormatData
        elif check_json_format(json.dumps(unitsBefore)):
            if columnName in unitsBefore.keys(): outFormatData = unitsBefore[columnName] + outFormatData
        else:
            outFormatData = unitsBefore + outFormatData
        if isinstance(replaceText, list):
            replaceFrom = replaceText[0]
            replaceTo = replaceText[1]
            for replaceIndex,replaceItem in enumerate(replaceFrom):
                if outFormatData.strip() == str(replaceItem).strip() and replaceIndex < len(replaceTo):
                    if replaceTo[replaceIndex] is None:
                        outFormatData = ""
                    else:
                        outFormatData = replaceTo[replaceIndex]
    return outFormatData


def wordtable(documentWord, contentRow, json_data, tableHead):
    content = contentRow["content"]
    datadef = lambda: None if "data" not in content.keys() else content["data"]
    pointdef = lambda:2 if "point" not in content.keys() else content["point"]
    unitsdef = lambda:"" if "units" not in content.keys() else content["units"]
    rowStardef = lambda:1 if "rowStar" not in content.keys() else int(content["rowStar"])
    colStardef = lambda:0 if "colStar" not in content.keys() else int(content["colStar"])
    bolddef = lambda:"" if "bold" not in content.keys() else content["bold"]
    phrasedef = lambda: "" if "phrase" not in content.keys() else content["phrase"]
    point,units,rowStar,colStar,bold,table,dataN,phrase,tablePosition = \
        pointdef(),unitsdef(),rowStardef(),colStardef(),bolddef(),None,datadef(),phrasedef(), ""
    if "index" in content.keys():
        table = documentWord.tables[int(content["index"])]
    else:
        if str(content["flag"]).strip().find("表") >= 0:
            tablePosition = str(content["flag"]).strip()
        else:
            tablePosition = "[表" + str(content["flag"]).strip() + "]"
        for activeTableIndex, activeTable in enumerate(documentWord.tables):
            if len(activeTable.rows) > rowStar and len(activeTable.columns) > colStar:
                try:
                    if str(activeTable.rows[rowStar].cells[colStar].text).find(tablePosition) > -1:
                        table = activeTable
                        break
                except Exception as e:
                    pass
        if tablePosition == "[表19]":
            testFlag = True
        if table is None:
            for activeTableIndex, activeTable in enumerate(documentWord.tables):
                for rowIndex in range(len(activeTable.rows)):
                    for colIndex in range(len(activeTable.columns)):
                        try:
                            if str(activeTable.rows[rowIndex].cells[colIndex].text).find(tablePosition) > -1:
                                table,rowStar,colStar = activeTable, rowIndex, colIndex
                                break
                        except Exception as e:
                            pass
                    if table:break
                if table: break

    if table:
        count = 0
        if tableHead is not None:
            position = tableHead["position"]
            for positionIndex, positionItem in enumerate(position):
                if tablePosition == str(positionItem):
                    table_cell_set(table, tableHead["cell"][positionIndex][0], tableHead["cell"][positionIndex][1],
                                   tableHead["cell"][positionIndex][0], str(tableHead["content"][positionIndex]))
        if dataN is not None:
            if isinstance(dataN,list):
                head,detailValid,outvalue=[],[],[]
                phrasedef = lambda:None if "phrase" not in content.keys() else content["phrase"]
                joinvaluedef = lambda: None if "joinvalue" not in content.keys() else content["joinvalue"]
                phrase,joinvalue,textRow,fromtext,analysis = phrasedef(),joinvaluedef(),"","",""
                if phrase:
                    value = [0] * len(phrase)
                    textRow = phrase
                    if joinvalue and "average" in joinvalue["outoption"] and "outvalue" in joinvalue.keys():
                        value = [0] * len(joinvalue["outvalue"])
                elif joinvalue:
                    value = [0] * len(joinvalue["outvalue"])
                else:
                    value = [0]
                if joinvalue and isinstance(joinvalue["outoption"], list):
                    for n in range(len(joinvalue["outoption"])):
                        outvalue.append(value)
                else:
                    outvalue = value
                for indexN, itemN in enumerate(dataN):
                    datafrom = json.loads(json_data[itemN])
                    headfrom = datafrom["head"][0]
                    if fromtext != "":
                        fromtext += "-"
                    if headfrom["analysis"] == "crosstabs" or headfrom["analysis"] == "comparemeans":
                        fromtext += str(headfrom["ColumnID"])
                    else:
                        fromtext += str(headfrom["variableID"])
                    if headfrom["count"] != 0:
                        count += headfrom["count"]
                        if headfrom["analysis"] == "frequency" or headfrom["analysis"] == "multiple" \
                                or headfrom["analysis"] == "wordcloud":
                            analysis = "crosstabs"
                            if phrase is not None:
                                if "outvalue" in joinvalue:
                                    setoutvalue = copy.deepcopy(outvalue)
                                    for indO, itemO in enumerate(joinvalue["outoption"]):
                                        for indV, itemV in enumerate(joinvalue["outvalue"]):
                                            setvalue = 0
                                            if isinstance(itemV, list):
                                                for indOV, itemOV in enumerate(itemV):
                                                    for dataItem in datafrom["detailValid"]:
                                                        if float(str(dataItem["value"])) == float(str(itemOV)):
                                                            setvalue += dataItem[itemO]
                                            else:
                                                for dataItem in datafrom["detailValid"]:
                                                    if float(str(dataItem["value"])) == float(str(itemV)):
                                                        setvalue += dataItem[itemO]
                                            setoutvalue[indO][indV] = setvalue
                                    detailValid.append(dict(valueRow=indexN,
                                                            textRow=headfrom["varLabel"],
                                                            valueColumn=indexN,
                                                            textColumn=phrase[indexN],
                                                            outvalue=setoutvalue))
                                else:
                                    for dataItem in datafrom["detailValid"]:
                                        setoutvalue = copy.deepcopy(outvalue)
                                        for indO, itemO in enumerate(joinvalue["outoption"]):
                                            setoutvalue[indO][indexN] = dataItem[itemO]
                                        if indexN == 0:
                                            detailValid.append(dict(valueRow=indexN, textRow=textRow,
                                                                    valueColumn=dataItem["value"],
                                                                    textColumn=dataItem["text"],
                                                                    outvalue=setoutvalue))
                                        else:
                                            flag,setoutvalue,rowNo = False,copy.deepcopy(outvalue),-1
                                            for sourceInd, sourceItem in enumerate(detailValid):
                                                if sourceItem["textColumn"] == dataItem["text"]:
                                                    setoutvalue = copy.deepcopy(sourceItem["outvalue"])
                                                    flag,rowNo = True,sourceInd
                                                    break
                                            for indO, itemO in enumerate(joinvalue["outoption"]):
                                                setoutvalue[indO][indexN] = dataItem[itemO]
                                            if not flag:
                                                detailValid.append(dict(valueRow=indexN, textRow=textRow,
                                                                        valueColumn=dataItem["value"],
                                                                        textColumn=dataItem["text"],
                                                                        outvalue=setoutvalue))
                                            else:
                                                detailValid[rowNo]["outvalue"] = copy.deepcopy(setoutvalue)
                            else:
                                setoutvalue = copy.deepcopy(outvalue)
                                for indO, itemO in enumerate(joinvalue["outoption"]):
                                    for indV, itemV in enumerate(joinvalue["outvalue"]):
                                        setvalue = 0
                                        if isinstance(itemV, list):
                                            for indOV, itemOV in enumerate(itemV):
                                                for dataItem in datafrom["detailValid"]:
                                                    if float(str(dataItem["value"])) == float(str(itemOV)):
                                                        setvalue += dataItem[itemO]
                                        else:
                                            for dataItem in datafrom["detailValid"]:
                                                if float(str(dataItem["value"])) == float(str(itemV)):
                                                    setvalue = dataItem[itemO]
                                        setoutvalue[indO][indV] = setvalue
                                detailValid.append(dict(valueRow=indexN, textRow=headfrom["varLabel"],
                                                        valueColumn=indexN,
                                                        textColumn=headfrom["varLabel"],
                                                        outvalue=setoutvalue))
                        elif headfrom["analysis"] == "crosstabs":
                            analysis = "crosstabs"
                            setoutvalue = copy.deepcopy(outvalue)
                            datafrom["detailValid"].sort(key=lambda x: x["valueRow"], reverse=False)
                            if phrase is not None:
                                for dataItem in datafrom["detailValid"]:
                                    flag = False
                                    for sourceInd, sourceItem in enumerate(detailValid):
                                        if sourceItem["textRow"] == dataItem["textRow"]:
                                            flag = True
                                            break
                                    if not flag:
                                        detailValid.append(dict(valueRow=dataItem["valueRow"],
                                                                textRow=dataItem["textRow"],
                                                                valueColumn=0,
                                                                textColumn=phrase,
                                                                outvalue=setoutvalue))
                                for sourceInd, sourceItem in enumerate(detailValid):
                                    setsourceoutvalue = copy.deepcopy(sourceItem["outvalue"])
                                    for indO, itemO in enumerate(joinvalue["outoption"]):
                                        setvalue = 0
                                        for dataItem in datafrom["detailValid"]:
                                            if sourceItem["textRow"] == dataItem["textRow"]:
                                                for indV, itemV in enumerate(joinvalue["outvalue"]):
                                                    if isinstance(itemV, list):
                                                        for indVO, itemVO in enumerate(itemV):
                                                            if dataItem["valueColumn"] == itemVO:
                                                                setvalue += dataItem[itemO]
                                                    else:
                                                        if dataItem["valueColumn"] == itemV:
                                                            setvalue += dataItem[itemO]
                                                    break
                                        for indP, itemP in enumerate(phrase):
                                            if str(itemP) == str(headfrom["ColumnID"]):
                                                setsourceoutvalue[indO][indP] = setvalue
                                    sourceItem["outvalue"] = copy.deepcopy(setsourceoutvalue)
                            else:
                                datatarget = []
                                for dataItem in datafrom["detailValid"]:
                                    flag = False
                                    for sourceInd, sourceItem in enumerate(datatarget):
                                        if sourceItem["textRow"] == dataItem["textRow"]:
                                            flag = True
                                            break
                                    if not flag:
                                            datatarget.append(dict(valueRow=dataItem["valueRow"],
                                                                   textRow=dataItem["textRow"],
                                                                   valueColumn=0,
                                                                   textColumn=joinvalue["outvalue"],
                                                                   outvalue=setoutvalue))
                                for sourceInd, sourceItem in enumerate(datatarget):
                                    setoutvalue = copy.deepcopy(sourceItem["outvalue"])
                                    for indO, itemO in enumerate(joinvalue["outoption"]):
                                        for indV, itemV in enumerate(joinvalue["outvalue"]):
                                            setvalue = 0
                                            if isinstance(itemV, list):
                                                for indOV, itemOV in enumerate(itemV):
                                                    for dataItem in datafrom["detailValid"]:
                                                        if dataItem["valueRow"] == sourceItem["valueRow"] and \
                                                                float(str(dataItem["value"])) == float(str(itemOV)):
                                                            setvalue += dataItem[itemO]
                                            else:
                                                for dataItem in datafrom["detailValid"]:
                                                    if dataItem["valueRow"] == sourceItem["valueRow"] and \
                                                            float(str(dataItem["value"])) == float(str(itemV)):
                                                        setvalue = dataItem[itemO]
                                            setoutvalue[indO][indV] = setvalue
                                    datatarget[sourceInd]["outvalue"] = copy.deepcopy(setoutvalue)
                                for sourceInd, sourceItem in enumerate(datatarget):
                                    detailValid.append(sourceItem)
                        elif headfrom["analysis"] == "means":
                            analysis = "comparemeans"
                            detailValid.append(headfrom)
                        elif headfrom["analysis"] == "comparemeans":
                            analysis = "comparemeans"
                            datafrom["detailValid"].sort(key=lambda x: x["valueRow"], reverse=False)
                            if "outvalue" in joinvalue:
                                setoutvalue = copy.deepcopy(outvalue)
                                for indO, itemO in enumerate(joinvalue["outoption"]):
                                    for indV, itemV in enumerate(joinvalue["outvalue"]):
                                        setvalue = 0
                                        if isinstance(itemV, list):
                                            for indOV, itemOV in enumerate(itemV):
                                                for dataItem in datafrom["detailValid"]:
                                                    if str(dataItem["valueRow"]) == itemOV:
                                                        setvalue += dataItem[itemO]
                                        else:
                                            for dataItem in datafrom["detailValid"]:
                                                if str(dataItem["valueRow"]) == itemV:
                                                    setvalue += dataItem[itemO]
                                        setoutvalue[indO][indV] = setvalue
                                detailValid.append(dict(valueRow=indexN,
                                                        textRow=phrase[indexN],
                                                        outvalue=setoutvalue))
                            else:
                                for dataItem in datafrom["detailValid"]:
                                    setoutvalue = copy.deepcopy(outvalue)
                                    for indO, itemO in enumerate(joinvalue["outoption"]):
                                        setoutvalue[indO][indexN] = dataItem[itemO]
                                    if indexN == 0:
                                        detailValid.append(dict(valueRow=dataItem["valueRow"],
                                                                textRow=dataItem["textRow"],
                                                                outvalue=setoutvalue))
                                    else:
                                        flag, setoutvalue, rowNo = False, copy.deepcopy(outvalue), -1
                                        for sourceInd, sourceItem in enumerate(detailValid):
                                            if sourceItem["textRow"] == dataItem["textRow"]:
                                                setoutvalue = copy.deepcopy(sourceItem["outvalue"])
                                                flag, rowNo = True, sourceInd
                                                break
                                        for indO, itemO in enumerate(joinvalue["outoption"]):
                                            setoutvalue[indO][indexN] = dataItem[itemO]
                                        if not flag:
                                            detailValid.append(dict(valueRow=dataItem["valueRow"],
                                                                    textRow=dataItem["textRow"],
                                                                    outvalue=setoutvalue))
                                        else:
                                            detailValid[rowNo]["outvalue"] = copy.deepcopy(setoutvalue)
                head.append(dict(varLabel='', variableID=fromtext, count = count,analysis=analysis))
            else:
                datasource = json.loads(json_data[content["data"]])
                head,detailValid = datasource["head"],datasource["detailValid"]
            if head[0]["analysis"] == "means":
                detailValid = head
            if head[0]["count"] != 0:
                if "sort" in content.keys():
                    if content["sort"]=="id":
                        detailValid.sort(key=lambda x: x["value"],reverse=False)
                    elif content["sort"]=="-id":
                        detailValid.sort(key=lambda x: x["value"],reverse=True)
                    elif content["sort"]=="per":
                        if head[0]["analysis"]=="multiple":
                            detailValid.sort(key=lambda x: x["casepercent"],reverse=False)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=False)
                    elif content["sort"]=="-per":
                        if head[0]["analysis"]=="multiple":
                            detailValid.sort(key=lambda x: x["casepercent"],reverse=True)
                        else:
                            detailValid.sort(key=lambda x: x["validpercent"],reverse=True)
                    elif content["sort"] == "avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=False)
                    elif content["sort"] == "-avg":
                        detailValid.sort(key=lambda x: x["average"], reverse=True)
                    elif content["sort"] == "rowid":
                        detailValid.sort(key=lambda x: x["valueRow"],reverse=False)
                    elif content["sort"] == "-rowid":
                        detailValid.sort(key=lambda x: x["valueRow"],reverse=True)
                    elif content["sort"] == 'columnid':
                        detailValid.sort(key=lambda x: x["valueColumn"],reverse=False)
                    elif content["sort"] == "-columnid":
                        detailValid.sort(key=lambda x: x["valueColumn"],reverse=True)
                outvalue = content["outvalue"]
                maxrow = 0
                if "breakdown" in content.keys():
                    maxrow = len(detailValid) // int(content["breakdown"])
                    if len(detailValid) % int(content["breakdown"]) > 0:
                        maxrow += 1
                if "rowvalue" in content.keys():
                    rowvalue = content["rowvalue"]
                    if isinstance(rowvalue, list):
                        for ind, rowitem in enumerate(rowvalue):
                            if isinstance(outvalue, list):
                                for indvalue, valueitem in enumerate(outvalue):
                                    setvalue = 0
                                    if isinstance(rowitem, list):
                                        for indV, rowitemV in enumerate(rowitem):
                                            for dataItem in detailValid:
                                                if float(str(rowitemV)) == float(str(dataItem["value"])):
                                                    setvalue += dataItem[valueitem]
                                    else:
                                        for dataItem in detailValid:
                                            if float(str(rowitem)) == float(str(dataItem["value"])):
                                                setvalue += dataItem[valueitem]
                                    if str(valueitem).find("per") > -1:
                                        table_cell_set(table, rowStar + ind, colStar + indvalue, rowStardef(),
                                                       formatdata(float(setvalue) * 100, point, "") + units)
                                    elif str(valueitem).find("av") > -1 or str(valueitem).find("median") > -1:
                                        table_cell_set(table, rowStar + ind, colStar + indvalue, rowStardef(),
                                                       formatdata(float(setvalue), point, "") + units)
                                    elif str(valueitem).find("std") > -1:
                                        table_cell_set(table, rowStar + ind, colStar + indvalue, rowStardef(),
                                                       formatdata(float(setvalue), point + 1, ""))
                                    else:
                                        table_cell_set(table, rowStar + ind, colStar + indvalue, rowStardef(),
                                                       str(setvalue))
                                    if isinstance(bold, list) and colStar + indvalue < len(bold):
                                        table.rows[rowStar + ind].cells[colStar + indvalue].paragraphs[0].runs[0].\
                                            font.bold = bold[colStar + indvalue]
                            else:
                                setvalue = 0
                                if isinstance(rowitem, list):
                                    for indV, rowitemV in enumerate(rowitem):
                                        for dataItem in detailValid:
                                            if float(str(rowitemV)) == float(str(dataItem["value"])):
                                                setvalue += dataItem[outvalue]
                                else:
                                    for dataItem in detailValid:
                                        if float(str(rowitem)) == float(str(dataItem["value"])):
                                            setvalue += dataItem[outvalue]
                                if str(outvalue).find("per") > -1:
                                    table_cell_set(table, rowStar + ind, colStar, rowStardef(),
                                                   formatdata(float(setvalue) * 100, point, "") + units)
                                elif str(outvalue).find("av") > -1 or str(outvalue).find("median") > -1:
                                    table_cell_set(table, rowStar + ind, colStar, rowStardef(),
                                                   formatdata(float(setvalue), point, "") + units)
                                elif str(outvalue).find("std") > -1:
                                    table_cell_set(table, rowStar + ind, colStar, rowStardef(),
                                                   formatdata(float(setvalue), point + 1, ""))
                                else:
                                    table_cell_set(table, rowStar + ind, colStar, rowStardef(), str(setvalue))
                                if isinstance(bold, list) and colStar < len(bold):
                                    table.rows[rowStar + ind].cells[colStar].paragraphs[0].runs[0].font.bold = bold[colStar]
                    else:
                        setvalue = 0
                        for dataItem in detailValid:
                            if float(str(rowvalue)) == float(str(dataItem["value"])):
                                setvalue += dataItem[outvalue]
                        rowstring = "{}"
                        if "rowstring" in content.keys():
                            rowstring = content["rowstring"]
                        if str(outvalue).find("per") > -1:
                            rowstring = rowstring.format(formatdata(float(setvalue) * 100, point, "") + units)
                        elif str(outvalue).find("av") > -1 or str(outvalue).find("median") > -1:
                            rowstring = rowstring.format(formatdata(float(setvalue), point, "") + units)
                        elif str(outvalue).find("std") > -1:
                            rowstring = rowstring.format(formatdata(float(setvalue), point + 1, ""))
                        else:
                            rowstring = rowstring.format(str(setvalue))
                        table_cell_set(table, rowStar, colStar, rowStardef(), rowstring)
                        if isinstance(bold, list) and colStar < len(bold):
                            table.rows[rowStar].cells[colStar].paragraphs[0].runs[0].font.bold = bold[colStar]
                else:
                    joinvalue = None
                    if "joinvalue" in content.keys():
                        phrasedef = lambda:None if "phrase" not in content.keys() else content["phrase"]
                        phrase,joinvalue,colindex = phrasedef(),content["joinvalue"],0
                        for ind, itemoutvalue in enumerate(outvalue):
                            if itemoutvalue == "outvalue":
                                colindex = ind
                                outvalue.remove(itemoutvalue)
                        if phrase is not None:
                            maxindex = len(phrase)
                            if joinvalue and "average" in joinvalue["outoption"] and "outvalue" in joinvalue.keys():
                                maxindex = len(joinvalue["outvalue"])
                        else:
                            maxindex = len(joinvalue["outvalue"])
                        if isinstance(joinvalue["outoption"], list):
                            for ind in range(maxindex):
                                for n in range(len(joinvalue["outoption"])):
                                    outvalue.insert(colindex, "outvalue-" + str(n) + "-" + str(ind))
                                    colindex += 1
                        else:
                            for ind in range(maxindex):
                                outvalue.insert(colindex, "outvalue-" + str(ind))
                                colindex += 1
                    mergerStardef = lambda:None if "mergerStar" not in content.keys() else content["mergerStar"]
                    mergerEnddef = lambda:None if "mergerEnd" not in content.keys() else content["mergerEnd"]
                    addrowdef = lambda:None if "addrow" not in content.keys() else content["addrow"]
                    mergerStar,mergerEnd,addrow = mergerStardef(),mergerEnddef(),addrowdef()
                    mergergroup, mergercode, cellStar, cellEnd = None,None,None,None
                    if isinstance(outvalue, list):
                        if len(table.columns) < len(outvalue):
                            for n in range(len(outvalue) - table.columns):
                                table.add_column(Cm(3))
                    if mergerStar is not None and isinstance(outvalue, list):
                        mergergroup,mergercode,cellStar,cellEnd = [None] * len(outvalue),[None] * len(outvalue),\
                                                                  [None] * len(outvalue),[None] * len(outvalue)
                        for ind, itemmerger in enumerate(mergerStar):
                            if itemmerger == "same":
                                if isinstance(mergerEnd[colStar + ind], list):
                                    mergergroup[mergerEnd[colStar + ind][len(mergerEnd[colStar + ind]) - 1]] = ""
                                    mergercode[mergerEnd[colStar + ind][len(mergerEnd[colStar + ind]) - 1]] = \
                                        mergerEnd[colStar + ind]
                                else:
                                    mergergroup[mergerEnd[colStar + ind]] = ""
                                    mergercode[mergerEnd[colStar + ind]] = mergerEnd[colStar + ind]
                    mergergroupitem = ""
                    for dataItem in detailValid:
                        if addrow is None and len(table.rows) <= rowStar + 1:
                            table.add_row()
                        if isinstance(outvalue, list):
                            for ind, itemoutvalue in enumerate(outvalue):
                                if mergerStar is not None and mergergroup[colStar + ind] is not None:
                                    if isinstance(mergercode[colStar + ind], list):
                                        for indgroup, itemgroup in enumerate(mergercode[colStar + ind]):
                                            mergergroupitem = "{0}{1}".\
                                                format(mergergroupitem,str(dataItem[outvalue[int(str(itemgroup))]]))
                                    else:
                                        mergergroupitem = str(dataItem[itemoutvalue])
                                if mergerStar is None or mergergroup[colStar + ind] is None or \
                                        (mergergroup[colStar + ind] is not None and
                                         mergergroup[colStar + ind] != mergergroupitem):
                                    if mergerStar is not None and mergergroup[colStar + ind] is not None:
                                        cellStar[colStar + ind] = [rowStar, colStar + ind]
                                        cellEnd[colStar + ind] = [rowStar, colStar + ind]
                                    if itemoutvalue in dataItem.keys():
                                        if str(itemoutvalue).find("per") > -1:
                                            table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                   formatdata(float(dataItem[itemoutvalue]) * 100, point, "") + units)
                                        elif str(itemoutvalue).find("av") > -1 or str(itemoutvalue).find("median") > -1:
                                            table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                           formatdata(float(dataItem[itemoutvalue]), point, "") + units)
                                        elif str(itemoutvalue).find("std") > -1:
                                            table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                           formatdata(float(dataItem[itemoutvalue]), point + 1, ""))
                                        else:
                                            table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                           str(dataItem[itemoutvalue]))
                                    else:
                                        if str(itemoutvalue).find("outvalue") > -1:
                                            outItem = str(itemoutvalue).replace("-", ",").split(',')
                                            if len(outItem) > 2:
                                                outColumn = joinvalue["outoption"][int(outItem[1])]
                                                outData = dataItem["outvalue"][int(outItem[1])][int(outItem[2])]
                                            else:
                                                outColumn = joinvalue["outoption"]
                                                outData = dataItem["outvalue"][int(outItem[1])]
                                            if str(outColumn).find("per") > -1:
                                                table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                               formatdata(float(outData) * 100, point, "") + units)
                                            elif str(outColumn).find("av") > -1 or str(outColumn).find("median") > -1:
                                                table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                               formatdata(float(outData), point, "") + units)
                                            elif str(outColumn).find("std") > -1:
                                                table_cell_set(table, rowStar, colStar + ind, rowStardef(),
                                                               formatdata(float(outData), point + 1, ""))
                                            else:
                                                table_cell_set(table, rowStar, colStar + ind, rowStardef(),str(outData))
                                        else:
                                            table_cell_set(table, rowStar, colStar + ind, rowStardef(), itemoutvalue)
                                else:
                                    if mergergroup[colStar + ind] is not None:
                                        cellEnd[colStar + ind][len(cellEnd[colStar + ind]) - 1][0] = rowStar
                                    table_cell_set(table, rowStar, colStar + ind, rowStardef(), "")
                                if isinstance(bold, list) and colStar + ind < len(bold):
                                    table.rows[rowStar].cells[colStar + ind].paragraphs[0].runs[0].font.bold = \
                                        bold[colStar + ind]
                                if mergerStar is not None and mergergroup[colStar + ind] is not None:
                                    mergergroup[colStar + ind] = mergergroupitem
                        else:
                            if outvalue in dataItem.keys():
                                if str(outvalue).find("per") > -1:
                                    table_cell_set(table, rowStar, 0, rowStardef(),
                                                   formatdata(float(dataItem[outvalue]) * 100, point, "")  + units)
                                elif str(outvalue).find("av") > -1 or str(outvalue).find("median") > -1:
                                    table_cell_set(table, rowStar, 0, rowStardef(),
                                                   formatdata(float(dataItem[outvalue]), point, "") + units)
                                elif str(outvalue).find("std") > -1:
                                    table_cell_set(table, rowStar, 0, rowStardef(),
                                                   formatdata(float(dataItem[outvalue]), point + 1, ""))
                                else:
                                    table_cell_set(table, rowStar, 0, rowStardef(), str(dataItem[outvalue]))
                            else:
                                table_cell_set(table, rowStar, 0, rowStardef(), outvalue)
                            if isinstance(bold, list):
                                table.rows[rowStar].cells[0].paragraphs[0].runs[0].font.bold = bold[colStar]
                        if "breakdown" in content.keys():
                            if rowStar == maxrow:
                                rowStar = rowStardef()
                                if isinstance(outvalue, list):
                                    colStar = colStar + len(outvalue)
                                else:
                                    colStar += 1
                            else:
                                rowStar += 1
                        else:
                            rowStar += 1
                    rowdelete = table.rows[len(table.rows) - 1]
                    rowdelete._element.getparent().remove(rowdelete._element)
                    if mergerStar is not None:
                        for n in range(len(outvalue)):
                            if cellStar[colStar + n] is not None:
                                for ind, cellitem in enumerate(cellStar[colStar + n]):
                                    if isinstance(cellitem, list) and isinstance(cellEnd[colStar + n][ind], list):
                                        table.cell(cellitem[0], cellitem[1]).merger\
                                            (table.cell(cellEnd[colStar + n][ind][0], cellEnd[colStar + n][ind][1]))
                        for ind, mergeritem in enumerate(mergerStar):
                            if mergeritem == "same":
                                pass
                            elif mergeritem == "maxrow":
                                table.cell(rowStar, mergerEnd[0]).merger(table.cell(rowStar, mergerEnd[1]))
                            else:
                                table.cell(mergerStar[0], mergerStar[1]).merger(table.cell(mergerEnd[0], mergerEnd[1]))
            else:
                table.cell(0, 0).text = "此题无相关数据！！！！！"
        else:
            rowPhrasedef = lambda: "" if "rowPhrase" not in content.keys() else content["rowPhrase"]
            rowTextdef = lambda: "" if "rowText" not in content.keys() else content["rowText"]
            outColumndef = lambda: "" if "outColumn" not in content.keys() else content["outColumn"]
            unitsBeforedef = lambda: "" if "unitsBefore" not in content.keys() else content["unitsBefore"]
            unitsAfterdef = lambda: "" if "unitsAfter" not in content.keys() else content["unitsAfter"]
            sortFirstdef = lambda: [] if "sortFirst" not in content.keys() else content["sortFirst"]
            sortLastdef = lambda: [] if "sortLast" not in content.keys() else content["sortLast"]
            positiondef = lambda: "" if "position" not in content.keys() else content["position"]
            sumColumndef = lambda: "" if "sumColumn" not in content.keys() else content["sumColumn"]
            replaceTextdef = lambda: "" if "replaceText" not in content.keys() else content["replaceText"]
            zeroFilldef = lambda: "" if "zeroFill" not in content.keys() else str(content["zeroFill"])
            phraseDatadef = lambda: "" if "phraseData" not in content.keys() else content["phraseData"]
            colorColStardef = lambda: 0 if "colorColStar" not in content.keys() else content["colorColStar"]
            colorColEnddef = lambda: -1 if "colorColEnd" not in content.keys() else content["colorColEnd"]
            parityLinedef = lambda: "" if "parityLine" not in content.keys() else content["parityLine"]
            colorColIndexdef = lambda: 0 if "colorColIndex" not in content.keys() else content["colorColIndex"]
            colorBgdef = lambda: "" if "colorBg" not in content.keys() else content["colorBg"]
            colorFontdef = lambda: "" if "colorFont" not in content.keys() else content["colorFont"]
            totalitydef = lambda: "" if "totality" not in content.keys() else content["totality"]
            equalArraydef = lambda: "" if "equalArray" not in content.keys() else content["equalArray"]
            colEnddef = lambda: "" if "colEnd" not in content.keys() else content["colEnd"]
            rowPhrase, rowTextAll, outColumn, unitsBefore, unitsAfter, fromtext, detailValid, columnMax, phraseData = \
                rowPhrasedef(),rowTextdef(),outColumndef(),unitsBeforedef(),unitsAfterdef(),"表",[], 0, phraseDatadef()
            sortFirst, sortLast, position, detailValidTotal, sumColumn, sumColumnData, replaceText, zeroFill = \
                sortFirstdef(), sortLastdef(), positiondef(), [], sumColumndef(), [], replaceTextdef(), zeroFilldef()
            colorColStar, parityLine, colorColIndex, totality, colorBg, colorFont, equalArray, colEnd, maxrow = \
                colorColStardef(), parityLinedef(), colorColIndexdef(), totalitydef(), colorBgdef(), colorFontdef(), \
                equalArraydef(), colEnddef(),0
            orderColumn, orderPoint, orderKey, sumColumnName, colorColEnd, columnStringBack, breakCount = \
                "", 0, 0, [], colorColEnddef(), {}, 1
            if len(sortFirst) != 0:
                rowNo, sortAll = -99999, sortFirst
            else:
                rowNo, sortAll = 99999, sortLast
            if isinstance(rowTextAll, list):
                rowText = rowTextAll[0]
            else:
                rowText = rowTextAll
            if rowText != "":
                detailValidTotal = rowDataProcess(outColumn, rowText, phrase, rowPhrase, rowNo,sortAll,json_data,
                                                  False, phraseData, "")
            else:
                for columnIndex in range(len(outColumn)):
                    detailValid.append(dict(value=int(columnIndex + 1)))
                    if isinstance(outColumn[columnIndex], list):
                        if len(outColumn[columnIndex]) > columnMax: columnMax = len(outColumn[columnIndex])
                        for indexCol in range(len(outColumn[columnIndex])):
                            detailValid = outDataProcess(outColumn[columnIndex][indexCol], indexCol, rowText, phrase,
                                                         json_data, detailValid, columnIndex, False, phraseData, "",
                                                         rowPhrase, columnStringBack)
                    else:
                        if len(outColumn) > columnMax: columnMax = len(outColumn)
                        detailValid = outDataProcess(outColumn[columnIndex], columnIndex, rowText, phrase, json_data,
                                                     detailValid, -1, False, phraseData, "", rowPhrase,columnStringBack)
                detailValidTotal.append(detailValid)
            for detailIndex in range(len(detailValidTotal)):
                if rowText != "":
                    for detailItem in detailValidTotal[detailIndex]:
                        if detailItem["columnMax"] > columnMax: columnMax = detailItem["columnMax"]
                if "sort" in content.keys():
                    if content["sort"] == "id":
                        detailValidTotal[detailIndex].sort(key=lambda x: x["value"], reverse=False)
                    elif content["sort"] == "-id":
                        detailValidTotal[detailIndex].sort(key=lambda x: x["value"], reverse=True)
                    elif content["sort"] == "text":
                        detailValidTotal[detailIndex].sort(key=lambda x: x["text"], reverse=False)
                    elif content["sort"] == "-text":
                        detailValidTotal[detailIndex].sort(key=lambda x: x["text"], reverse=True)
                    elif content["sort"] == "textNum":
                        detailValidTotal[detailIndex].sort(key=lambda x: sort_key(x["textColumn"], False),reverse=False)
                    elif content["sort"] == "-textNum":
                        detailValidTotal[detailIndex].sort(key=lambda x: sort_key(x["textColumn"], True), reverse=True)
                    else:
                        if str(content["sort"]).find(",") > -1:
                            sortKey, sortWord = str(content["sort"]).split(','), False
                            if str(sortKey[0]).find("-") >= 0: sortWord = True
                            if sortKey[0].find('id') > -1 or sortKey[0].find('text') > -1:
                                sortKey[0] = str(sortKey[0]).replace("-", "")
                                if sortKey[0] == 'id': sortKey[0] = 'value'
                            else:
                                if rowText != "":
                                    sortKey[0] = "column" + str(int(str(sortKey[0]).replace("-", "")) - 1)
                                else:
                                    sortKey[0] = "column" + str(sortKey[0]).replace("-", "")
                            if sortKey[1].find('id') > -1 or sortKey[1].find('text') > -1:
                                sortKey[1] = str(sortKey[1]).replace("-", "")
                                if sortKey[1] == 'id': sortKey[1] = 'value'
                            else:
                                if rowText != "":
                                    sortKey[1] = "column" + str(int(str(sortKey[1]).replace("-", "")) - 1)
                                else:
                                    sortKey[1] = "column" + str(sortKey[1]).replace("-", "")
                            if sortWord:
                                detailValidTotal[detailIndex].sort(key=lambda x: (sort_key(x[str(sortKey[0])], True),
                                                                sort_key(x[str(sortKey[1])], True)), reverse=True)
                            else:
                                detailValidTotal[detailIndex].sort(key=lambda x: (sort_key(x[str(sortKey[0])], False),
                                                                sort_key(x[str(sortKey[1])], False)), reverse=False)
                        else:
                            if str(content["sort"]).find('id') > -1 or str(content["sort"]).find('text') > -1:
                                sortKey = str(content["sort"]).replace("-", "")
                                if sortKey == 'id': sortKey = 'value'
                            else:
                                if rowText != "":
                                    sortKey = "column" + str(int(str(content["sort"]).replace("-", "")) - 1)
                                else:
                                    sortKey = "column" + str(content["sort"]).replace("-", "")
                            if str(content["sort"]).find("-") >= 0:
                                detailValidTotal[detailIndex].sort(key=lambda x: sort_key(x[str(sortKey)], True), reverse=True)
                            else:
                                detailValidTotal[detailIndex].sort(key=lambda x: sort_key(x[str(sortKey)], False), reverse=False)
                else:
                    if rowText != "":
                        detailValidTotal[detailIndex].sort(key=lambda x: x["value"], reverse=False)
            if sumColumn != "":
                for sumIndex in range(columnMax):
                    sumColumnData.append(0)
                    sumColumnName.append("")
            if "breakdown" in content.keys():
                maxrow = len(detailValidTotal[0]) // int(content["breakdown"]) + rowStardef() - 1
                if len(detailValidTotal[0]) % int(content["breakdown"]) > 0:
                    maxrow += 1
                breakCount = int(content["breakdown"])
            mergerStardef = lambda: None if "mergerStar" not in content.keys() else content["mergerStar"]
            mergerEnddef = lambda: None if "mergerEnd" not in content.keys() else content["mergerEnd"]
            mergerColumndef = lambda: None if "mergerColumn" not in content.keys() else content["mergerColumn"]
            addrowdef = lambda: None if "addrow" not in content.keys() else content["addrow"]
            mergerStar, mergerEnd, mergerColumn, addrow = mergerStardef(), mergerEnddef(), mergerColumndef(),addrowdef()
            mergerColumnNM, columnMerger, mergerRowStar, mergerRowEnd, mergerColumnGroup, mergerCount = \
                [], [], [], [], [], []
            if mergerColumn is not None:
                for mergerIndex in range(len(mergerColumn)):
                    mergerColumnNM.append("")
                    columnMerger.append("")
                    mergerRowStar.append([])
                    mergerRowEnd.append([])
                    mergerColumnGroup.append("")
                    mergerCount.append("0")
            textRow, indexStar, tableColAdd, rowIndex = ["text"], 0, 1, 0
            if isinstance(rowTextAll, list) and rowTextAll[1] != "":
                rowText = ""
            if rowText == "":
                textRow, indexStar, tableColAdd = ["column0"], 1, 0
            if mergerColumn is not None and len(mergerColumn) > 0:
                for mergerColumnIndex, mergerColumnItem in enumerate(mergerColumn):
                    if mergerColumnItem.find('column') > -1:
                        mergerColumn[mergerColumnIndex] = \
                            'column' + str(int(mergerColumnItem.replace('column', '')) - 1 + indexStar)
            if (isinstance(rowPhrase, list) and len(rowPhrase) > 0) or \
                (isinstance(rowPhrase, str) and rowPhrase.find("data") > -1 and rowPhrase.find(":") > -1):
                textRow,tableColAdd = ["phrase","text"], 2
            if isinstance(rowPhrase, str) and rowPhrase.find("data") > -1 and rowPhrase.find(":") > -1 and \
                rowPhrase.find(";") > -1:
                textRow, tableColAdd = ["headPhrase", "phrase", "text"], 3
            if isinstance(point, list):
                if len(point) > orderKey + tableColAdd:
                    orderPoint = point[orderKey + tableColAdd]
                else:
                    orderPoint = point[len(point) - 1]
            else:
                orderPoint = point
            if len(table.columns) < breakCount * (columnMax + tableColAdd) and colEnd == "":
                for n in range(breakCount * (columnMax + tableColAdd) - len(table.columns)):
                    table.add_column(Cm(3))
            for detailValidTotalIndex,detailValidTotalItem in enumerate(detailValidTotal):
                detailRemove, detailLast = [], []
                for detailIndex, detailItem in enumerate(detailValidTotalItem):
                    removeFlag = True
                    for indexColumn in range(columnMax):
                        if isinstance(outColumn[0], list):
                            if is_fromData(str(outColumn[detailItem["rowIndex"]][indexColumn])) and \
                                    detailItem["column" + str(indexColumn)] is not None and \
                                    detailItem["column" + str(indexColumn)] != "" and \
                                    ((is_number(sort_key(detailItem["column" + str(indexColumn)], None)) and
                                      float(str(sort_key(detailItem["column" + str(indexColumn)], None))) != 0.0) or
                                     (str(detailItem["columnName" + str(indexColumn)]).find("text") > -1 and
                                      detailItem["column" + str(indexColumn)] != "")):
                                removeFlag = False
                                break
                        else:
                            if is_fromData(str(outColumn[indexColumn])) and \
                                    detailItem["column" + str(indexColumn)] is not None and \
                                    detailItem["column" + str(indexColumn)] != "" and \
                                    ((is_number(sort_key(detailItem["column" + str(indexColumn)], None)) and
                                     float(str(sort_key(detailItem["column" + str(indexColumn)], None))) != 0.0) or
                                     (str(detailItem["columnName" + str(indexColumn)]).find("text") > -1 and
                                      detailItem["column" + str(indexColumn)] != "")):
                                removeFlag = False
                                break
                    if zeroFill != "":
                        for indexColumn in range(columnMax):
                            if detailItem["column" + str(indexColumn)] is None:
                                detailValidTotal[detailValidTotalIndex][detailIndex]["column" + str(indexColumn)] = 0
                    if removeFlag:
                        detailRemove.append(detailItem)
                    else:
                        if rowText == "":
                            sortLastText = str(detailItem["column0"]).strip()
                        else:
                            sortLastText = str(detailItem["text"]).strip()
                        if sortLastText in sortLast:
                            detailRemove.append(detailItem)
                            detailLast.append(detailItem)
                for indexRemove,itemRemove in enumerate(detailRemove):
                    detailValidTotalItem.remove(itemRemove)
                for indexLast,itemLast in enumerate(detailLast):
                    detailValidTotalItem.append(itemLast)
            try:
                for detailTotalIndex in range(len(detailValidTotal)):
                    if sumColumn != "" and detailTotalIndex > 0:
                        for sumIndex in range(columnMax):
                            sumColumnData[sumIndex] = 0
                            sumColumnName[sumIndex] = ""
                    detailValid = detailValidTotal[detailTotalIndex]
                    if addrow is not None  and is_number_int(addrow) and int(addrow) > 0 and orderColumn != "":
                        if isinstance(rowTextAll, list) and rowTextAll[1] != "":
                            addrow = returncountRepeat(detailValid, int(addrow), orderColumn, orderPoint)
                        else:
                            addrow = returncount(detailValid, int(addrow), orderColumn, orderPoint)
                    if isinstance(rowTextAll, list) and rowTextAll[1] == "True" and addrow < len(detailValid):
                        detailValidRepeat = []
                        for indexRemove in range(addrow - 1, -1, -1):
                            detailValidRepeat.append(detailValid[indexRemove])
                        detailValid = detailValidRepeat
                    for detailIndex, detailItem in enumerate(detailValid):
                        rowIndex += 1
                        if addrow is not None and is_number_int(addrow) and int(addrow) != 0:
                            if rowStar > int(addrow):
                                break
                        if (addrow is None or (addrow is not None and is_number_int(addrow) and int(addrow) != 0)) and \
                                len(table.rows) <= rowStar + 1:
                            table.add_row()
                        for textIndex in range(len(textRow)):
                            outputFlag, mergerFlag = False, False
                            if mergerColumn is not None:
                                for mergerIndex in range(len(mergerColumn)):
                                    if str(mergerColumn[mergerIndex]).strip() == textRow[textIndex]:
                                        mergerFlag = True
                                        if str(detailItem[mergerColumn[mergerIndex]]).strip()!=mergerColumnGroup[mergerIndex]:
                                            mergerColumnGroup[mergerIndex]=str(detailItem[mergerColumn[mergerIndex]]).strip()
                                            outputFlag = True
                            if textRow[textIndex] == "column0":
                                textRowName = detailItem["columnName0"]
                            else:
                                textRowName = textRow[textIndex]
                            if not mergerFlag:
                                table_cell_set(table, rowStar, colStar + textIndex, rowStardef(),
                                               outputFormatData(detailItem[textRow[textIndex]], textRowName, point,
                                                                textIndex, unitsBefore, unitsAfter, replaceText, rowIndex))
                            else:
                                if outputFlag:
                                    table_cell_set(table, rowStar, colStar + textIndex, rowStardef(),
                                               outputFormatData(detailItem[textRow[textIndex]], textRowName, point,
                                                                textIndex,unitsBefore, unitsAfter, replaceText, rowIndex))
                                else:
                                    table_cell_set(table, rowStar, colStar + textIndex, rowStardef(), "")
                            if mergerColumn is not None:
                                for mergerIndex in range(len(mergerColumn)):
                                    if textRow[textIndex] == str(mergerColumn[mergerIndex]):
                                        columnMerger[mergerIndex] = str(colStar + textIndex)
                                        if mergerColumnNM[mergerIndex] != str(detailItem[textRow[textIndex]]).strip():
                                            mergerRowStar[mergerIndex].append(str(rowStar))
                                        if mergerColumnNM[mergerIndex].strip() != "" and \
                                            mergerColumnNM[mergerIndex] != str(detailItem[textRow[textIndex]]).strip():
                                            mergerRowEnd[mergerIndex].append(str(rowStar - 1))
                                        mergerColumnNM[mergerIndex] = str(detailItem[textRow[textIndex]]).strip()
                                        columnMerger[mergerIndex] = str(colStar + textIndex)
                                        break
                        for indexColumn in range(indexStar, columnMax):
                            outputFlag, mergerFlag = False, False
                            if mergerColumn is not None:
                                for mergerIndex in range(len(mergerColumn)):
                                    if str(mergerColumn[mergerIndex]).strip() == "column" + str(indexColumn):
                                        mergerFlag = True
                                        if str(detailItem[mergerColumn[mergerIndex]]).strip()!=mergerColumnGroup[mergerIndex]:
                                            mergerColumnGroup[mergerIndex]=str(detailItem[mergerColumn[mergerIndex]]).strip()
                                            outputFlag = True
                            if not mergerFlag:
                                table_cell_set(table, rowStar, colStar + indexColumn + tableColAdd, rowStardef(),
                                               outputFormatData(detailItem["column" + str(indexColumn)],
                                                                detailItem["columnName" + str(indexColumn)], point,
                                               indexColumn + tableColAdd, unitsBefore, unitsAfter, replaceText, rowIndex))
                            else:
                                if outputFlag:
                                    table_cell_set(table, rowStar, colStar + indexColumn + tableColAdd, rowStardef(),
                                                   outputFormatData(detailItem["column" + str(indexColumn)],
                                                                    detailItem["columnName" + str(indexColumn)], point,
                                                   indexColumn + tableColAdd,unitsBefore,unitsAfter, replaceText, rowIndex))
                                else:
                                    table_cell_set(table, rowStar, colStar + indexColumn + tableColAdd, rowStardef(), "")
                            if sumColumn != "":
                                if detailItem["column" + str(indexColumn)] is not None:
                                    sumColumnData[indexColumn] += detailItem["column" + str(indexColumn)]
                                sumColumnName[indexColumn] = detailItem["columnName" + str(indexColumn)]
                            if mergerColumn is not None:
                                for mergerIndex in range(len(mergerColumn)):
                                    if "column" + str(indexColumn).strip() == str(mergerColumn[mergerIndex]):
                                        columnMerger[mergerIndex] = str(colStar + indexColumn + tableColAdd)
                                        if mergerColumnNM[mergerIndex]!=str(detailItem["column"+str(indexColumn)]).strip():
                                            mergerRowStar[mergerIndex].append(str(rowStar))
                                        if mergerColumnNM[mergerIndex].strip() != "" and mergerColumnNM[mergerIndex] != \
                                                str(detailItem["column" + str(indexColumn)]).strip():
                                            mergerRowEnd[mergerIndex].append(str(rowStar - 1))
                                        mergerColumnNM[mergerIndex] = str(detailItem["column" + str(indexColumn)]).strip()
                                        columnMerger[mergerIndex] = str(colStar + indexColumn + tableColAdd)
                                        break
                        if isinstance(colorColStar, dict):
                            for keyColStar, valueColStar in colorColStar.items():
                                if keyColStar == "colorBg" and isinstance(parityLine, str) and parityLine != "":
                                    tabBgColor(table, rowStar, colorColStar, colorColEnd, colorBg, parityLine,
                                               colorColIndex, totality)
                                else:
                                    for valueColStarIndex, valueColStarItem in enumerate(valueColStar):
                                        if keyColStar in colorColEnd and isinstance(colorColEnd[keyColStar], list) and \
                                            str(colorColEnd[keyColStar][valueColStarIndex]).strip() != "":
                                                colorColEndItem = int(str(colorColEnd[keyColStar][valueColStarIndex]).strip())
                                        else:
                                            colorColEndItem = len(table.columns)
                                        if keyColStar in colorColIndex and isinstance(colorColIndex[keyColStar], list) and \
                                            str(colorColIndex[keyColStar][valueColStarIndex]).strip() != "":
                                                colorColIndexItem = str(colorColIndex[keyColStar][valueColStarIndex]).strip()
                                        else:
                                            colorColIndexItem = ""
                                        if keyColStar in equalArray and isinstance(equalArray[keyColStar], list) :
                                                if isinstance(equalArray[keyColStar][valueColStarIndex], list) and \
                                                    len(equalArray[keyColStar][valueColStarIndex]) > 0:
                                                    equalArrayItem = equalArray[keyColStar][valueColStarIndex]
                                                else:
                                                    equalArrayItem = ""
                                        else:
                                            equalArrayItem = ""
                                        if keyColStar in colorFont and isinstance(colorFont[keyColStar], list):
                                                colorFontItem = colorFont[keyColStar][valueColStarIndex]
                                        else:
                                            colorFontItem = ""
                                        if keyColStar in parityLine and isinstance(parityLine[keyColStar], list):
                                                parityLineItem = parityLine[keyColStar][valueColStarIndex]
                                        else:
                                            parityLineItem = ""
                                        if parityLineItem != '':
                                            tabBgColor(table, rowStar, valueColStarItem, colorColEndItem, colorFontItem,
                                                       parityLineItem, colorColIndexItem, totality)
                                        else:
                                            table_font_color_bold(table, rowStar, valueColStarItem, colorColEndItem,
                                                                  colorColIndexItem, equalArrayItem, colorFontItem,
                                                                  keyColStar)
                        else:
                            if colorColEnd == -1: colorColEnd = len(table.columns)
                            if isinstance(colorBg, list):
                                for colorBgIndex, colorBgItem in enumerate(colorBg):
                                    if str(colorBgItem).strip() != "":
                                        if isinstance(colorColStar, list):
                                            if colorBgIndex < len(colorColStar):
                                                colorColStarItem = colorColStar[colorBgIndex]
                                            else:
                                                colorColStarItem = colorColStar[0]
                                        else:
                                            colorColStarItem = colorColStar
                                        if isinstance(parityLine, list):
                                            if colorBgIndex < len(parityLine):
                                                parityLineItem = parityLine[colorBgIndex]
                                            else:
                                                parityLineItem = parityLine[0]
                                        else:
                                            parityLineItem = parityLine
                                        if isinstance(colorColIndex, list):
                                            if colorBgIndex < len(colorColIndex):
                                                colorColIndexItem = colorColIndex[colorBgIndex]
                                            else:
                                                colorColIndexItem = colorColIndex[0]
                                        else:
                                            colorColIndexItem = colorColIndex
                                        if isinstance(totality, list):
                                            if colorBgIndex < len(totality):
                                                totalityItem = totality[colorBgIndex]
                                            else:
                                                totalityItem = totality[0]
                                        else:
                                            totalityItem = totality
                                        tabBgColor(table, rowStar, colorColStarItem, colorColEnd, colorBgItem, parityLineItem,
                                                   colorColIndexItem, totalityItem)
                            else:
                                if str(colorBg).strip() != "":
                                    tabBgColor(table, rowStar, colorColStar, colorColEnd, colorBg, parityLine,colorColIndex,
                                               totality)
                            if isinstance(bold, list) or (isinstance(bold, str) and bold.strip() != "") or \
                                isinstance(colorFont, list):
                                if isinstance(colorColStar, list):
                                    font_paragraph(table, rowStar, bold, colorFont, colorColStar[0], colorColEnd,
                                                   colorColIndex, equalArray)
                                else:
                                    font_paragraph(table, rowStar, bold, colorFont, colorColStar, colorColEnd,
                                                   colorColIndex, equalArray)
                        if "breakdown" in content.keys():
                            if rowStar == maxrow:
                                rowStar = rowStardef()
                                colStar = colStar + columnMax + tableColAdd
                            else:
                                rowStar += 1
                        else:
                            rowStar += 1
                    if sumColumn != "":
                        rowIndex += 1
                        if addrow is None and len(table.rows) <= rowStar + 1:
                            table.add_row()
                        table_cell_set(table, rowStar, colStar, rowStardef(), sumColumn)
                        for indexColumn in range(indexStar, columnMax):
                            sumValue = None
                            if len(sumColumnData) > indexColumn: sumValue = sumColumnData[indexColumn]
                            table_cell_set(table, rowStar, colStar + indexColumn + tableColAdd, rowStardef(),
                                           outputFormatData(sumValue, sumColumnName[indexColumn], point,
                                                            indexColumn  + tableColAdd, unitsBefore, unitsAfter,
                                                            replaceText, rowIndex))
                        rowStar += 1
                if "breakdown" in content.keys() and maxrow > 0:rowStar = maxrow + 1
                if addrow is None or (is_number_int(addrow) and int(addrow) != 0):
                    for rowDeleteIndex in range(rowStar, len(table.rows)):
                        rowdelete = table.rows[len(table.rows) - 1]
                        rowdelete._element.getparent().remove(rowdelete._element)
                if mergerColumn is not None:
                    for mergerIndex in range(len(mergerColumn)):
                        if len(mergerRowStar[mergerIndex]) > len(mergerRowEnd[mergerIndex]):
                            mergerRowEnd[mergerIndex].append(str(rowStar - 1))
                        for rowIndex in range(len(mergerRowStar[mergerIndex])):
                            if int(mergerRowStar[mergerIndex][rowIndex]) < int(mergerRowEnd[mergerIndex][rowIndex]) and \
                                    rowIndex < len(mergerRowEnd[mergerIndex]) and mergerRowEnd[mergerIndex][rowIndex] != "":
                                if rowStar > int(mergerRowEnd[mergerIndex][rowIndex]) > \
                                    int(mergerRowStar[mergerIndex][rowIndex]):
                                    table.cell(int(mergerRowStar[mergerIndex][rowIndex]), int(columnMerger[mergerIndex]))\
                                        .merge(table.cell(int(mergerRowEnd[mergerIndex][rowIndex]),
                                                           int(columnMerger[mergerIndex])))
                                    delete_paragraph(table, mergerRowStar[mergerIndex][rowIndex],
                                                     int(columnMerger[mergerIndex]))
                            else:
                                if mergerRowStar[mergerIndex][rowIndex].strip() != "" and \
                                    int(mergerRowStar[mergerIndex][rowIndex]) != int(mergerRowEnd[mergerIndex][rowIndex]) and\
                                    rowStar - 1 > int(mergerRowStar[mergerIndex][rowIndex]):
                                    table.cell(int(mergerRowStar[mergerIndex][rowIndex]), int(columnMerger[mergerIndex])) \
                                        .merge(table.cell(rowStar - 1, int(columnMerger[mergerIndex])))
                                    delete_paragraph(table, mergerRowStar[mergerIndex][rowIndex],
                                                     int(columnMerger[mergerIndex]))
                if mergerStar is not None:
                    for ind, mergeritem in enumerate(mergerStar):
                        if mergeritem == "maxrow":
                            if isinstance(mergerEnd[0], list):
                                for mergerItem in mergerEnd:
                                    if mergerItem[0] < len(table.columns) and mergerItem[1] < len(table.columns):
                                        mergerText0, mergerText1 = "", ""
                                        for paragraph in table.rows[rowStar - 1].cells[mergerItem[0]].paragraphs:
                                            mergerText0 += paragraph.text.strip()
                                        for paragraph in table.rows[rowStar - 1].cells[mergerItem[1]].paragraphs:
                                            mergerText1 += paragraph.text.strip()
                                        if mergerText0 != "" and mergerText1 != "":
                                            table_cell_set(table, rowStar - 1, mergerItem[1], rowStardef(), "")
                                        table.cell(rowStar - 1, mergerItem[0]).merge(table.cell(rowStar - 1, mergerItem[1]))
                                        delete_paragraph(table, rowStar - 1, mergerItem[0])
                            else:
                                if mergerEnd[0] < len(table.columns) and mergerEnd[1] < len(table.columns):
                                    mergerText0, mergerText1 = "", ""
                                    for paragraph in table.rows[rowStar - 1].cells[mergerEnd[0]].paragraphs:
                                        mergerText0 += paragraph.text.strip()
                                    for paragraph in table.rows[rowStar - 1].cells[mergerEnd[1]].paragraphs:
                                        mergerText1 += paragraph.text.strip()
                                    if mergerText0 != "" and mergerText1 != "":
                                        table_cell_set(table, rowStar - 1, mergerEnd[1], rowStardef(), "")
                                    table.cell(rowStar - 1, mergerEnd[0]).merge(table.cell(rowStar - 1, mergerEnd[1]))
                                    delete_paragraph(table, rowStar - 1, mergerEnd[0])
                        else:
                            if isinstance(mergeritem[0], list) and isinstance(mergerEnd[0], list):
                                for mergeritemInd, mergeritemStar in enumerate(mergeritem):
                                    if mergeritemInd < len(mergerEnd) and mergeritemStar[0] < len(table.rows) and \
                                            mergerEnd[mergeritemInd][0] < len(table.rows) and \
                                            mergeritemStar[1] < len(table.columns) and \
                                            mergerEnd[mergeritemInd][1] < len(table.columns):
                                        table.cell(mergeritemStar[0], mergeritemStar[1]).merge(
                                            table.cell(mergerEnd[mergeritemInd][0], mergerEnd[mergeritemInd][1]))
                                        delete_paragraph(table, mergeritemStar[0], mergeritemStar[1])
                            else:
                                if mergerStar[0] < len(table.rows) and mergerEnd[0] < len(table.rows) and \
                                        mergerStar[1] < len(table.columns) and mergerEnd[1] < len(table.columns):
                                    table.cell(mergerStar[0], mergerStar[1]).merge(table.cell(mergerEnd[0], mergerEnd[1]))
                                    delete_paragraph(table, mergerStar[0], mergerStar[1])
            except Exception as e:
                print(tablePosition)
                pass
    return None


def delete_paragraph(table, rowStar, columnIndex):
    try:
        for paragraph in table.rows[int(rowStar)].cells[columnIndex].paragraphs:
            if str(paragraph.text) == "":
                p = paragraph._element
                p.getparent().remove(p)
                # p._p = p._element = None
                paragraph._p = paragraph._element = None
    except Exception as e:
        pass


def alignment_paragraph(table, rowStar, columnIndex):
    try:
        for paragraph in table.rows[int(rowStar)].cells[columnIndex].paragraphs:
            if str(paragraph.text) != "":
                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
    except Exception as e:
        pass


def table_cell_set(table, rowIndex, columnIndex, firstRow, contect, fromContect=None):
    try:
        paragraphsFirst, style = table.rows[firstRow].cells[columnIndex].paragraphs, None
        for paragraph in paragraphsFirst:
            style = paragraph.style

        firstRowHeight = table.rows[firstRow]
        table.rows[rowIndex].height = firstRowHeight.height
        firstRowColumn = table.rows[firstRow].cells[columnIndex]
        table.rows[rowIndex].cells[columnIndex].vertical_alignment = firstRowColumn.vertical_alignment
        paragraphs = table.rows[rowIndex].cells[columnIndex].paragraphs
        for paragraph in paragraphs:
            if fromContect is not None:
                if str(paragraph.text).find(fromContect) > -1:
                    paragraph.text = str(paragraph.text).replace(fromContect, contect)
            else:
                paragraph.text = contect
            if style is not None:
                paragraph.style = style
    except Exception as e:
        pass


def table_font_color_bold(table, rowIndex, colStar, cols, colLine, equalArray, colorStr, flag):
    try:
        if is_number(colLine) and colLine != "": colLine = int(colLine)
        shading_list = locals()
        if equalArray == "":
            for colIndex in range(int(colStar), cols + 1):
                if flag == "colorFont" or flag == "bold":
                    paragraphs = table.rows[rowIndex].cells[colIndex].paragraphs
                    for paragraph in paragraphs:
                        for run in paragraph.runs:
                            if flag == "bold":
                                run.font.bold = True
                            else:
                                run.font.color.rgb = RGBColor(int(colorStr[0]), int(colorStr[1]), int(colorStr[2]))
                else:
                    shading_list['shading_elm_' + str(colIndex)] = parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.
                                                                             format(nsdecls('w'), bgColor=colorStr))
                    table.rows[rowIndex].cells[colIndex]._tc.get_or_add_tcPr(). \
                        append(shading_list['shading_elm_' + str(colIndex)])
        else:
            tableText = ""
            if isinstance(colLine, int):
                for paragraph in table.rows[rowIndex].cells[colLine].paragraphs:
                    tableText += paragraph.text.strip()
            for colIndex in range(int(colStar), cols + 1):
                if tableText == "":
                    for paragraph in table.rows[rowIndex].cells[colLine].paragraphs:
                        tableText += paragraph.text.strip()
                if tableText in equalArray:
                    if flag == "colorFont" or flag == "bold":
                        paragraphs = table.rows[rowIndex].cells[colIndex].paragraphs
                        for paragraph in paragraphs:
                            for run in paragraph.runs:
                                if flag == "bold":
                                    run.font.bold = True
                                else:
                                    run.font.color.rgb = RGBColor(int(colorStr[0]), int(colorStr[1]), int(colorStr[2]))
                    else:
                        shading_list['shading_elm_' + str(colIndex)] = \
                            parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'), bgColor=colorStr))
                        table.rows[rowIndex].cells[colIndex]._tc.get_or_add_tcPr(). \
                            append(shading_list['shading_elm_' + str(colIndex)])
    except Exception as e:
        pass


def font_paragraph(table, rowIndex, bold, colorStr, colStar, cols, colLine, equalArray):
    try:
        if is_number(colLine):colLine = int(colLine)
        if isinstance(bold, list) or (isinstance(bold, str) and bold != ""):
            if isinstance(bold, list):
                if isinstance(bold[0], list):
                    tableText, boldFlag = "", False
                    for paragraph in table.rows[rowIndex].cells[colLine].paragraphs:
                        tableText += paragraph.text.strip()
                    if tableText in bold[0]:
                        boldFlag = True
                    if boldFlag:
                        for colIndex in bold[1]:
                            if colIndex < cols:
                                paragraphs = table.rows[rowIndex].cells[int(colIndex)].paragraphs
                                for paragraph in paragraphs:
                                    for run in paragraph.runs:
                                        run.font.bold = True
                else:
                    for boldItem in bold:
                        paragraphs = table.rows[rowIndex].cells[int(boldItem)].paragraphs
                        for paragraph in paragraphs:
                            for run in paragraph.runs:
                                run.font.bold = True
            else:
                if int(bold) < cols:
                    paragraphs = table.rows[rowIndex].cells[int(bold)].paragraphs
                    for paragraph in paragraphs:
                        for run in paragraph.runs:
                            run.font.bold = True
        if isinstance(colorStr, list):
            if isinstance(colorStr[0], list):
                for colIndex in range(int(colStar), cols):
                    for colorIndex, colorItem in enumerate(colorStr):
                        if str(table.rows[rowIndex].cells[colIndex].text).strip() in equalArray[colorIndex]:
                            paragraphs = table.rows[rowIndex].cells[colIndex].paragraphs
                            for paragraph in paragraphs:
                                for run in paragraph.runs:
                                    run.font.color.rgb = RGBColor(colorItem[0],colorItem[1],colorItem[2])
            else:
                if str(table.rows[rowIndex].cells[colLine].text).strip() in equalArray:
                    if colStar != "":
                        for colIndex in range(int(colStar), cols):
                            paragraphs = table.rows[rowIndex].cells[colIndex].paragraphs
                            for paragraph in paragraphs:
                                for run in paragraph.runs:
                                    run.font.color.rgb = RGBColor(colorStr[0],colorStr[1],colorStr[2])
                    else:
                        paragraphs = table.rows[rowIndex].cells[colLine].paragraphs
                        for paragraph in paragraphs:
                            for run in paragraph.runs:
                                run.font.color.rgb = RGBColor(colorStr[0], colorStr[1], colorStr[2])
    except Exception as e:
        pass


def tabBgColor(table, rowIndex, colStar, cols, colorStr, parityLine, colLine, totality):
    try:
        shading_list = locals()
        if is_number(colLine): colLine = int(colLine)
        for colIndex in range(int(colStar), cols + 1):
            if parityLine == "":
                if str(totality).strip() != "":
                    tableText = ""
                    for paragraph in table.rows[rowIndex].cells[colLine].paragraphs:
                        tableText += paragraph.text.strip()
                    if tableText == str(totality).strip():
                        shading_list['shading_elm_' + str(colIndex)] = \
                            parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'),bgColor=colorStr))
                        table.rows[rowIndex].cells[colIndex]._tc.get_or_add_tcPr(). \
                            append(shading_list['shading_elm_' + str(colIndex)])
                else:
                    shading_list['shading_elm_'+str(colIndex)] = parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.
                                                                    format(nsdecls('w'),bgColor = colorStr))
                    table.rows[rowIndex].cells[colIndex]._tc.get_or_add_tcPr().\
                        append(shading_list['shading_elm_'+str(colIndex)])
            else:
                parityLineInt = int(parityLine)
                if (rowIndex + parityLineInt) % 2 == 0:
                    shading_list['shading_elm_' + str(colIndex)] = parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.
                                                                             format(nsdecls('w'), bgColor=colorStr))
                    table.rows[rowIndex].cells[colIndex]._tc.get_or_add_tcPr(). \
                        append(shading_list['shading_elm_' + str(colIndex)])
    except Exception as e:
        pass


def is_fromData(columnString):
    if columnString.find("data") > -1:
        if columnString.find(":") > -1 or columnString.find("+") > -1 or \
            columnString.find("-") > -1 or columnString.find("*") > -1  or columnString.find("/") > -1:
            return True
        else:
            return False
    else:
        if is_number(columnString):
            return True
        else:
            return False


def passRate(passString, json_data):
    division = passString.split('/')
    molecules,moleculesCount,moleculesDataIndex = division[0].split(','),0,0
    denominator,denominatorCount,denominatorDataIndex = division[1].split(','),0,0
    for moleculesIndex, moleculesItem in enumerate(molecules):
        datasource = json.loads(json_data[moleculesItem])
        if moleculesIndex == 0:
            moleculesCount = len(datasource["detailValid"])
        else:
            if moleculesCount > len(datasource["detailValid"]):
                moleculesCount = len(datasource["detailValid"])
                moleculesDataIndex = moleculesIndex
    for denominatorIndex, denominatorItem in enumerate(denominator):
        datasource = json.loads(json_data[denominatorItem])
        if denominatorIndex == 0:
            denominatorCount = len(datasource["detailValid"])
        else:
            if denominatorCount > len(datasource["detailValid"]):
                denominatorCount = len(datasource["detailValid"])
                denominatorDataIndex = denominatorIndex
    datasource = json.loads(json_data[molecules[moleculesDataIndex]])
    moleculesData = copy.deepcopy(datasource["detailValid"])
    datasource = json.loads(json_data[denominator[denominatorDataIndex]])
    denominatorData = copy.deepcopy(datasource["detailValid"])
    for moleculesIndex, moleculesItem in enumerate(molecules):
        if moleculesIndex != moleculesDataIndex:
            datasource = json.loads(json_data[molecules[moleculesIndex]])
            for dataItem in moleculesData:
                dataFlag = False
                for detailValidItem in datasource["detailValid"]:
                    if dataItem['text'] == detailValidItem['text']:
                        dataFlag = True
                        break
                if not dataFlag:
                    moleculesCount -= 1
    for denominatorIndex, denominatorItem in enumerate(denominator):
        if denominatorIndex != denominatorDataIndex:
            datasource = json.loads(json_data[denominator[denominatorIndex]])
            for dataItem in denominatorData:
                dataFlag = False
                for detailValidItem in datasource["detailValid"]:
                    if dataItem['text'] == detailValidItem['text']:
                        dataFlag = True
                        break
                if not dataFlag:
                    denominatorCount -= 1
    if denominatorCount == 0:
        return 0
    else:
        return (moleculesCount / denominatorCount) * 100


def percentileRank(percentileRankString, json_data):
    division = percentileRankString.split('/')
    datasource = json.loads(json_data[division[0]])
    head = datasource['head'][0]
    datasource = json.loads(json_data[division[1]])
    detailValid = datasource["detailValid"]
    average = head['average']
    moleculesCount, denominatorCount = 0, len(detailValid)
    detailValid.sort(key=lambda x: x["average"], reverse=False)
    for detailValidItem in detailValid:
        if detailValidItem['average'] <= average:
            moleculesCount += 1
        else:
            break
    if denominatorCount == 0:
        return 0
    else:
        return (moleculesCount / denominatorCount) * 100


def formatdata(_data: float, _len: int, _type = None) -> object:
    formatstr, _len = '{:.2f}', int(_len)
    if _len == 0:
        text = Decimal(str(_data)).quantize(Decimal('1.'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.0f}'
    elif _len == 1:
        text = Decimal(str(_data)).quantize(Decimal('0.1'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.1f}'
    elif _len == 2:
        text = Decimal(str(_data)).quantize(Decimal('0.01'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.2f}'
    elif _len == 3:
        text = Decimal(str(_data)).quantize(Decimal('0.001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.3f}'
    elif _len == 4:
        text = Decimal(str(_data)).quantize(Decimal('0.0001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.4f}'
    elif _len == 5:
        text = Decimal(str(_data)).quantize(Decimal('0.00001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.5f}'
    elif _len == 6:
        text = Decimal(str(_data)).quantize(Decimal('0.000001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.6f}'
    elif _len == 7:
        text = Decimal(str(_data)).quantize(Decimal('0.0000001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.7f}'
    elif _len == 8:
        text = Decimal(str(_data)).quantize(Decimal('0.00000001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.8f}'
    elif _len == 9:
        text = Decimal(str(_data)).quantize(Decimal('0.000000001'), rounding = "ROUND_HALF_UP")
        formatstr = '{:.9f}'
    else:
        text = Decimal(str(_data)).quantize(Decimal('1.'), rounding = "ROUND_HALF_UP")
    if _type is None:
        if _len == 0:
            text = str(round(text))
        else:
            text = formatstr.format(float(text))
    elif _type == "c":
        if _len == 0:
            text = round(text)
        else:
            text = float(text)
    else:
        if _len == 0:
            text = str(round(text))
        else:
            text = str(text)
    return text


def formatchart(_units, _point):
    if _units=="":
        text=json.dumps(dict(format="%." + str(_point) + "f"))
    else:
        formatstring = ["per", "%." + str(_point) + "f"]
        text=json.dumps(dict(format=formatstring))
    return json.loads(text)


def returncount(dataList, topN, column, pointStr):
    point = 2
    if isinstance(pointStr, str) and pointStr != "":point = int(pointStr)
    if isinstance(pointStr, int):point = pointStr
    if column == "validpercent" or column == "casepercent" or column == "passRate" or column == "masteryRate" or \
            column == "percentileRank":
        point += 2
    if topN >= len(dataList):
        return len(dataList)
    else:
        if float(str(formatdata(sort_key(dataList[topN - 1][column], None), point))) != \
                float(str(formatdata(sort_key(dataList[topN][column], None), point))):
            if column == "validpercent" and topN > 2:
                countFlag = True
                for topNIndex in range(topN - 1):
                    if float(str(formatdata(dataList[topNIndex][column], point))) != 1.0:
                        countFlag = False
                        break
                if float(str(formatdata(dataList[topN - 1][column], point))) == 1.0:
                    countFlag = False
                if countFlag:
                    topN -= 1
            if (column == "casepercent" or column == "validpercent" or column == "average") and topN > 2:
                countFlag = True
                if column == "validpercent":
                    if abs(dataList[topN - 2][column] - dataList[topN - 1][column]) < 0.19:
                        countFlag = False
                elif column == "average":
                    for dataListItem in dataList:
                        if dataListItem[column] < 0 or dataListItem[column] > 5:
                            countFlag = False
                    if abs(dataList[topN - 2][column] - dataList[topN - 1][column]) < 1.5:
                        countFlag = False
                else:
                    if abs(dataList[topN - 2][column] - dataList[topN - 1][column]) < 0.09:
                        countFlag = False
                    if abs(dataList[topN - 3][column] - dataList[topN - 2][column]) > 0.03:
                        countFlag = False
                if countFlag:
                    topN -= 1
            return topN
        else:
            if topN <= 2:
                topN+=1
                for num in range(topN - 1, len(dataList) - 1):
                    if float(str(formatdata(sort_key(dataList[num][column], None), point))) == \
                            float(str(formatdata(sort_key(dataList[num + 1][column], None), point))):
                        topN+=1
                    else:
                        break
            else:
                if float(str(formatdata(sort_key(dataList[topN - 2][column], None), point))) != \
                        float(str(formatdata(dataList[topN - 1][column], point))):
                    topN-=1
                else:
                    topN+=1
                    for num in range(topN - 1, len(dataList) - 1):
                        if float(str(formatdata(sort_key(dataList[num][column], None), point))) == \
                                float(str(formatdata(sort_key(dataList[num + 1][column], None), point))):
                            topN+=1
                        else:
                            break
            return topN


def returncountRepeat(dataList, topN, column, pointStr):
    point,dataRepeat = 2, []
    if isinstance(pointStr, str) and pointStr != "":point = int(pointStr)
    if isinstance(pointStr, int):point = pointStr
    if column == "validpercent" or column == "casepercent" or column == "passRate" or column == "masteryRate" or \
            column == "percentileRank":
        point += 2
    if topN >= len(dataList):
        return len(dataList)
    else:
        for index in range(topN):
            if float(str(formatdata(sort_key(dataList[index][column], None), point))) not in dataRepeat:
                dataRepeat.append(float(str(formatdata(sort_key(dataList[index][column], None), point))))
        if topN != len(dataRepeat):
            topRepeat = topN
            for index in range(topRepeat, len(dataList)):
                if float(str(formatdata(sort_key(dataList[index][column], None), point))) not in dataRepeat:
                    dataRepeat.append(float(str(formatdata(sort_key(dataList[index][column], None), point))))
                    topN += 1
                    if topRepeat == len(dataRepeat):
                        break
                else:
                    topN += 1
        topRepeat = topN
        for index in range(topRepeat, len(dataList)):
            if float(str(formatdata(sort_key(dataList[index - 1][column], None), point))) == \
                    float(str(formatdata(sort_key(dataList[index][column], None), point))):
                topN += 1
            else:
                break
    return topN


def topk_partition(dataList, topN, column, point):
    """
    输出matrix矩阵的最大/小前k个值的index，无序
    所对应的top k的值：matrix[index[i][0], index[i][1]]
                        matrix[index[i]]
    :param dataList:
    :param topN:
    :param column:
    :param point:
    :return:
    """
    matrix,top_max = [], True
    if dataList[0][column] < dataList[len(dataList)][column]:
        top_max = False
    for num in range(len(dataList)):
        matrix.append(float(str(formatdata(dataList[num][column], point))))
    matrix = np.array(matrix)
    flag_2d = False
    if len(matrix.shape) == 2:
        flag_2d = True
        matrix1 = matrix.reshape((matrix.shape[0] * matrix.shape[1]))
    else:
        matrix1 = matrix.copy()
    if top_max:  # matrix前k个最大值 所对应的index
        index = np.argpartition(matrix1, -topN)[-topN:len(matrix1)]
    else:  # matrix前k个最小值 所对应的index
        index = np.argpartition(matrix1, topN - 1)[0:topN]

    # 解析index
    if flag_2d:
        index_2d = []
        for num in index:
            rowIndex = num // matrix.shape[1]
            col = num % matrix.shape[1]
            index_2d.append([rowIndex, col])
        index = index_2d

    return index


def replacetext(text, replaceText):
    replaceString = ["、、", "，，", "；；", "。。", "、，", "，；", "、；", "，。", "；。", "。，", "。；", "。、", "、。"]
    newString = ["、", "，", "；", "。", "，", "；", "；", "。", "。", "。", "。", "。", "。"]
    num_dict = ['零', '一', '两', '三', '四', '五', '六', '七', '八', '九']
    for index in range(20):
        for j in range(len(replaceString)):
            if text.find(replaceString[j]) > -1:
                text = str(text).replace(replaceString[j], newString[j])
    if isinstance(replaceText, list):
        replaceFrom = replaceText[0]
        replaceTo = replaceText[1]
        for replaceIndex, replaceItem in enumerate(replaceFrom):
            if text.find(str(replaceItem).strip()) > -1 and replaceIndex < len(replaceTo):
                text = str(text).replace(str(replaceItem).strip(), replaceTo[replaceIndex])
            else:
                if str(replaceItem).strip() == ".XX" and text.find("%") >-1 and is_number(text.replace("%", "")) and \
                        replaceIndex < len(replaceTo):
                    if replaceTo[replaceIndex] == "":
                        text = str(int(float(text.replace("%", "")))) + "%"
                    else:
                        text = num_dict[int(float(text.replace("%", "")) / 10)] + replaceTo[replaceIndex]
    return text


def is_number(s):
    try:  # 如果能运行float(s)语句，返回True（字符串s是浮点数）
        if isinstance(s, list):
            return False
        else:
            float(s)
            return True
    except ValueError:  # ValueError为Python的一种标准异常，表示"传入无效的参数"
        pass  # 如果引发了ValueError这种异常，不做任何事情（pass：不做任何事情，一般用做占位语句）
    try:
        import unicodedata  # 处理ASCii码的包
        for n in s:
            unicodedata.numeric(n)  # 把一个表示数字的字符串转换为浮点数返回的函数
            #return True
        return True
    except (TypeError, ValueError):
        pass
    return False


def sort_key(s, flag):
    # 排序关键字匹配
    # 匹配开头数字序号
    if isinstance(s, str) and not is_number(s) and s != 'None':
        try:
            if not (s.find("10月") > -1 or s.find("11月") > -1 or s.find("12月") > -1):
                replaceOld = ["1月","2月","3月","4月","5月","6月","7月","8月","9月"]
                replaceNew = ["01月", "02月", "03月", "04月", "05月", "06月", "07月", "08月", "09月"]
                for replaceIndex, replaceItem in enumerate(replaceOld):
                    s = s.replace(replaceItem, replaceNew[replaceIndex])
            if s.find("月1日") > -1 or s.find("月2日") > -1 or s.find("月3日") > -1 or s.find("月4日") > -1 or \
                    s.find("月5日") > -1 or s.find("月6日") > -1 or s.find("月7日") > -1 or s.find("月8日") > -1 or \
                    s.find("月9日") > -1:
                replaceOld = ["1日", "2日", "3日", "4日", "5日", "6日", "7日", "8日", "9日"]
                replaceNew = ["01日", "02日", "03日", "04日", "05日", "06日", "07日", "08日", "09日"]
                for replaceIndex, replaceItem in enumerate(replaceOld):
                    s = s.replace(replaceItem, replaceNew[replaceIndex])
            if s.find("年") > -1 and (s.find("月") > -1 or s.find("日") > -1):
                c = float("".join(list(filter(str.isdigit, s))))
                return c
            else:
                return s
        except:
            return s
    else:
        if s is None or s == "None":
            if flag is None:
                return 0
            else:
                if flag:
                    return -999999999
                else:
                    return 999999999
        elif is_number(s) and isinstance(s, str):
            return float(s)
        else:
            return s


def myAnalysis(PlatID, ProjID, mongodb_cfg, analysis, Condition, replaceCondition, rowDelete, TempID):
    json_data, json_data_flag, json_data_template,dataSetIdIndex = {}, True, {},[]

    for analysisRow in analysis:
        try:
            if str(analysisRow["index"]) == "480":
                testFlag = True
            phrase, phrase2, OptionID, fullMarks, denominator, noCondition, variableGroup, optionGroup, rangeData, \
            phraseText, equalRange, divide, weight, point, deleteRow, idText, json_data_save =  \
                "", "", "", "","", "", "", "", "", "", "","", "", "", "", "", True
            if "phrase" in analysisRow.keys():  phrase = analysisRow["phrase"]
            if "phrase2" in analysisRow.keys(): phrase2 = analysisRow["phrase2"]
            if "equalRange" in analysisRow.keys(): equalRange = analysisRow["equalRange"]
            if "divide" in analysisRow.keys(): divide = str(analysisRow["divide"])
            if "phraseText" in analysisRow.keys(): phraseText = analysisRow["phraseText"]
            if "OptionID" in analysisRow.keys(): OptionID = analysisRow["OptionID"]
            if "noCondition" in analysisRow.keys(): noCondition = str(analysisRow["noCondition"]).strip()
            if "range" in analysisRow.keys(): rangeData = analysisRow["range"]
            if "weight" in analysisRow.keys(): weight = analysisRow["weight"]
            if "point" in analysisRow.keys(): point = analysisRow["point"]
            if "deleteRow" in analysisRow.keys(): deleteRow = analysisRow["deleteRow"]
            if "idText" in analysisRow.keys(): idText = analysisRow["idText"]
            if rowDelete: deleteRow = ""
            if "fullMarks" in analysisRow.keys():
                fullMarks,fullMarksNum = str(analysisRow["fullMarks"]).strip(), 0.0
                if fullMarks.find(':') >= 0 and analysisRow["algorithm"] != "percentileRank2":
                    dataFrom = str(fullMarks).strip().split(':')
                    datasource = json.loads(json_data[dataFrom[0]])
                    if datasource["head"][0]["analysis"] == "comparemeans" and str(dataFrom[1]).strip().find("sum") > -1:
                        if str(dataFrom[1]).strip() == "sum":
                            fullMarks = datasource["detailValid"]
                            if "fullMarksDividend" in analysisRow.keys():
                                sumData = str(analysisRow["fullMarksDividend"]).strip().split(':')
                                for detailValidIndex, detailValidItem in enumerate(datasource["detailValid"]):
                                    if str(sumData[0]).strip() == str(detailValidItem["textRow"]).strip():
                                        fullMarks[detailValidIndex][str(dataFrom[1]).strip()] = \
                                            detailValidItem[str(dataFrom[1]).strip()] / float(sumData[1])
                        else:
                            fullMarks = datasource["detailValid"]
                            sumData = str(dataFrom[1]).strip().split('/')
                            if is_number(sumData[1]):
                                for detailValidIndex, detailValidItem in enumerate(datasource["detailValid"]):
                                    fullMarks[detailValidIndex][sumData[0]] = \
                                        detailValidItem[sumData[0]] / float(sumData[1])
                            else:
                                for detailValidIndex, detailValidItem in enumerate(datasource["detailValid"]):
                                    fullMarks[detailValidIndex][sumData[0]] = \
                                        detailValidItem[sumData[0]] / float(detailValidItem[sumData[1]])
                    else:
                        for detailValidItem in datasource["detailValid"]:
                            fullMarksNum += float(str(detailValidItem[dataFrom[1]]))
                        fullMarks = str(fullMarksNum)
            if "variableGroup" in analysisRow.keys():
                variableGroup = analysisRow["variableGroup"]
                if isinstance(variableGroup, str) and variableGroup.find(':') >= 0:
                    dataFrom = str(variableGroup).strip().split(':')
                    datasource = json.loads(json_data[dataFrom[0]])
                    variableGroup = []
                    for detailValidItem in datasource["detailValid"]:
                        variableGroup.append(detailValidItem[dataFrom[1]])
            if "optionGroup" in analysisRow.keys():
                optionGroup = analysisRow["optionGroup"]
                if isinstance(optionGroup, str) and optionGroup.find(':') >= 0:
                    dataFrom = str(optionGroup).strip().split(':')
                    datasource = json.loads(json_data[dataFrom[0]])
                    optionGroup = []
                    for detailValidItem in datasource["detailValid"]:
                        optionGroup.append(detailValidItem[dataFrom[1]])
            if "denominator" in analysisRow.keys():
                dataFrom = str(analysisRow["denominator"]).strip().split(':')
                datasource = json.loads(json_data[dataFrom[0]])
                head = datasource["head"][0]
                if head["analysis"] == "means":
                    denominator = str(head[dataFrom[1]]).strip()
                else:
                    detailValid = datasource["detailValid"]
                    denominator = []
                    denominatorText = []
                    denominatorData = []
                    for dataItem in detailValid:
                        denominatorText.append(dataItem["textRow"])
                        denominatorData.append(dataItem[dataFrom[1]])
                    denominator.append(denominatorText)
                    denominator.append(denominatorData)
            if not isinstance(deleteRow, dict) and str(deleteRow).strip() != "":
                if analysisRow["algorithm"] == "crosstabs":
                    deleteRow = {"total": int(deleteRow)}
                else:
                    deleteRow = {"count": int(deleteRow)}
            if noCondition != "" and TempID != "":
                if not json_data_template:
                    json_data_mongo = mongo_analysis_template_select(PlatID, mongodb_cfg, ProjID, TempID)
                    for json_data_mongo_item in json_data_mongo:
                        json_data_template = json_data_mongo_item
                        break
            if replaceCondition is not None and "filter" in analysisRow and isinstance(analysisRow["filter"], dict) and\
                    str(analysisRow["filter"]) != "":
                for filterKey, filterValue in analysisRow["filter"].items():
                    for replaceItem in replaceCondition:
                        for keyReplace, valueReplace in replaceItem.items():
                            if filterKey == keyReplace:
                                json_data_save = False
            if noCondition != "" and TempID != "" and json_data_template and json_data_save and \
                    'data' + str(analysisRow["index"]) in json_data_template['json_data'].keys():
                json_data['data' + str(analysisRow["index"])] = \
                    json_data_template['json_data']['data' + str(analysisRow["index"])]
            else:
                if analysisRow["algorithm"] == "frequency":
                    datasource = mongo_frequency_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                       analysisRow["variable"], phrase, weight, point, idText, deleteRow,
                                                       caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                     noCondition,json_data, replaceCondition))
                elif analysisRow["algorithm"] == "means":
                    if "variable" in analysisRow.keys():
                        datasource = mongo_means_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                       analysisRow["variable"], variableGroup, optionGroup, rangeData,
                                                       phrase, fullMarks, denominator, weight,
                                                       caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                     noCondition, json_data, replaceCondition))
                    else:
                        datasource = mongo_means_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]), "",
                                                       variableGroup, optionGroup, rangeData, phrase, fullMarks,
                                                       denominator, weight,
                                                       caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                     noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "means2":
                    if isinstance(variableGroup, str) and str(variableGroup) == "":
                        variableGroup = [analysisRow["variable"]]
                    datasource = mongo_means2_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                    variableGroup, optionGroup, phrase, fullMarks, denominator, weight,
                                                    caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                  noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "multiple":
                    if (isinstance(OptionID, str) and OptionID == "") and str(analysisRow["variable"]).find(',') < 0:
                        datasource = mongo_multiple_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                          analysisRow["variable"], phrase, weight,
                                                          caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                        noCondition, json_data, replaceCondition))
                    else:
                        datasource = mongo_multiple2_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                          analysisRow["variable"], phrase, OptionID, weight,
                                                          caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                         noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "wordcloud":
                    datasource = mongo_wordcloud_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                       analysisRow["variable"], phrase,
                                                       caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                     noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "crosstabs":
                    if "group" in analysisRow.keys():
                        datasource = mongo_crosstabs_logic(PlatID, mongodb_cfg, ProjID,
                                                           str(analysisRow["dataSourceId"]), analysisRow["RowID"],
                                                           analysisRow["ColumnID"], analysisRow["group"], deleteRow,
                                                           idText, weight,
                                                           caseCondition(PlatID, mongodb_cfg, ProjID, Condition, analysisRow,
                                                                         noCondition, json_data, replaceCondition))
                    else:
                        datasource = mongo_crosstabs_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                           analysisRow["RowID"], analysisRow["ColumnID"],
                                                           None, deleteRow, idText, weight,
                                                           caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                         noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "comparemeans":
                    if "ColumnID" in analysisRow.keys():
                        datasource = mongo_comparemeans_logic(PlatID, mongodb_cfg, ProjID,
                                                              str(analysisRow["dataSourceId"]), analysisRow["RowID"],
                                                              analysisRow["ColumnID"], variableGroup, optionGroup,
                                                              rangeData, denominator, deleteRow, idText, weight,
                                                              caseCondition(PlatID, mongodb_cfg, ProjID, Condition, analysisRow,
                                                                            noCondition, json_data, replaceCondition))
                    else:
                        datasource = mongo_comparemeans_logic(PlatID, mongodb_cfg, ProjID,
                                                              str(analysisRow["dataSourceId"]),
                                                              analysisRow["RowID"], "", variableGroup, optionGroup,
                                                              rangeData, denominator, deleteRow, idText, weight,
                                                              caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                            noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "comparemeans2":
                    if isinstance(variableGroup, str) and str(variableGroup) == "":
                        variableGroup = [analysisRow["ColumnID"]]
                    datasource = mongo_comparemeans2_logic(PlatID, mongodb_cfg, ProjID,str(analysisRow["dataSourceId"]),
                                                           analysisRow["RowID"], variableGroup, optionGroup,
                                                           denominator, deleteRow, idText, weight,
                                                           caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                         noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "sort1":
                    datasource = mongo_sort_logic(PlatID, mongodb_cfg, ProjID,
                                                  str(analysisRow["dataSourceId"]),
                                                  analysisRow["VariableID1"],
                                                  analysisRow["VariableID2"],
                                                  analysisRow["VariableID3"],
                                                  caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "sort2":
                    if isinstance(phrase, list) and isinstance(OptionID, list):
                        phraseNew = {}
                        for optionIndex, optionItem in enumerate(OptionID):
                            if optionIndex < len(phrase):
                                phraseNew[optionItem] = phrase[optionIndex]
                        phrase = phraseNew
                    datasource = mongo_sort2_logic(PlatID, mongodb_cfg, ProjID, str(analysisRow["dataSourceId"]),
                                                   analysisRow["variable"], phrase,
                                                   caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow,
                                                                 noCondition, json_data, replaceCondition))
                elif analysisRow["algorithm"] == "percentileRank" or analysisRow["algorithm"] == "percentileRank2"  or \
                        analysisRow["algorithm"] == "percentileRank3":
                    if "filter1" in analysisRow.keys():
                        Condition1 = analysisRow["filter1"]
                        if check_json_format(json.dumps(Condition1)):
                            keys,values = [],[]
                            for key, value in Condition1.items():
                                keys.append(key)
                                if check_json_format(json.dumps(value)):
                                    valueNew = {}
                                    for keyWords, valueWords in value.items():
                                        if str(keyWords).strip() == "lte" or str(keyWords).strip() == "gte" or \
                                                str(keyWords).strip() == "gt" or str(keyWords).strip() == "lt" or \
                                                str(keyWords).strip() == "nin" or str(keyWords).strip() == "in" or \
                                                str(keyWords).strip() == "regex" or str(keyWords).strip() == "ne" :
                                            if isinstance(valueWords, str) and str(valueWords).find(':') > -1:
                                                dataFrom = str(valueWords).strip().split(':')
                                                datasource = json.loads(json_data[dataFrom[0]])
                                                valueWords = datasource["head"][0][dataFrom[1]]
                                            if isinstance(equalRange, str) and str(equalRange) != "":
                                                equalRangeData = str(equalRange).strip().split(':')
                                                if is_number(valueWords) and valueWords - math.floor(valueWords) == 0\
                                                        and keyWords == equalRangeData[0]:
                                                    keyWords = equalRangeData[1]
                                            keyWords = "$" + str(keyWords).strip()
                                        if replaceCondition is not None:
                                            for replaceItem in replaceCondition:
                                                for keyReplace, valueReplace in replaceItem.items():
                                                    if key == keyReplace:
                                                        valueWords = valueReplace
                                        valueNew[keyWords] = valueWords
                                    values.append(valueNew)
                                else:
                                    if isinstance(value, str) and str(value).find(':') > -1:
                                        dataFrom = str(value).strip().split(':')
                                        datasource = json.loads(json_data[dataFrom[0]])
                                        value = datasource["head"][0][dataFrom[1]]
                                    if replaceCondition is not None:
                                        for replaceItem in replaceCondition:
                                            for keyReplace, valueReplace in replaceItem.items():
                                                if key == keyReplace:
                                                    value = valueReplace
                                    values.append(value)
                            Condition1 = dict(zip(keys, values))
                    else:
                        Condition1 = None
                    Condition2 = caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow, "", json_data,
                                               replaceCondition)
                    Condition3 = caseCondition(PlatID, ProjID, mongodb_cfg, Condition, analysisRow, "false", json_data,
                                               replaceCondition)
                    if analysisRow["algorithm"] == "percentileRank":
                        datasource = mongo_percentileRank_logic(PlatID, mongodb_cfg, ProjID,
                                                                str(analysisRow["dataSourceId1"]),
                                                                str(analysisRow["dataSourceId2"]),
                                                                str(analysisRow["RowID"]),
                                                                str(analysisRow["variable1"]),
                                                                analysisRow["variable2"],variableGroup, phrase, phraseText,
                                                                fullMarks, divide, Condition1, Condition2, Condition3)
                    elif analysisRow["algorithm"] == "percentileRank2":
                        datasource = mongo_percentileRank2_logic(PlatID, mongodb_cfg, ProjID,
                                                                 str(analysisRow["dataSourceId1"]),
                                                                 str(analysisRow["dataSourceId2"]),
                                                                 str(analysisRow["RowID"]),
                                                                 str(analysisRow["variable1"]),
                                                                 analysisRow["variable2"], variableGroup, phrase, phrase2,
                                                                 phraseText, fullMarks, divide, Condition1, Condition2,
                                                                 Condition3)
                    elif analysisRow["algorithm"] == "percentileRank3":
                        datasource = mongo_percentileRank3_logic(PlatID, mongodb_cfg, ProjID,
                                                                 str(analysisRow["dataSourceId1"]),
                                                                 str(analysisRow["dataSourceId2"]),
                                                                 str(analysisRow["RowID"]),
                                                                 str(analysisRow["variable1"]),
                                                                 analysisRow["variable2"], variableGroup, phrase, phrase2,
                                                                 phraseText, fullMarks, divide, Condition1, Condition2,
                                                                 Condition3)
                    else:
                        datasource = mongo_percentileRank4_logic(PlatID, mongodb_cfg, ProjID,
                                                                 str(analysisRow["dataSourceId1"]),
                                                                str(analysisRow["dataSourceId2"]),
                                                                str(analysisRow["RowID"]),
                                                                str(analysisRow["variable1"]),
                                                                analysisRow["variable2"], variableGroup, phrase, phraseText,
                                                                fullMarks, divide, Condition1, Condition2, Condition3)
                else:
                    datasource = None
                if datasource is not None:
                    json_data['data' + str(analysisRow["index"])] = json.dumps(datasource)
        except Exception as ex:
            json_data_flag = False
    return json_data, json_data_flag


def myTemplateUpdate(PlatID, ProjID, TempID, mongodb_cfg, templateItem):
    mongo_template_back_delete(PlatID, mongodb_cfg, ProjID, TempID)
    templateJson = dict(platId=PlatID, projId=ProjID, tempId=TempID, template=templateItem)
    mongo_template_back_insert(mongodb_cfg, templateJson)


def myTemplateCheck(PlatID, ProjID, TempID, mongodb_cfg, analysis):
    templateBack = mongo_template_back(PlatID, mongodb_cfg, ProjID, TempID)
    for templateBackItem in templateBack:
        templateBackData = templateBackItem["template"]
        for rowItem in templateBackData:
            if rowItem["type"] == "analy":
                analysisBack = rowItem["analy"]
                if json.dumps(analysisBack) == json.dumps(analysis):
                    return True
                else:
                    mongo_analysis_delete(PlatID, mongodb_cfg, ProjID, TempID)
                    return False
    return False


def myReport(documentDocx, content, json_data, chartfile, tableHead, replaceText, replaceChart):
    try:
        #lock.acquire()
        textDiscription, tableDiscription, tableIndexDiscription = worddiscriptionTextAndTable(documentDocx)
        for contentRow in content:
            if contentRow["type"] == "text":
                try:
                    worddiscription(documentDocx, contentRow, json_data, chartfile, replaceText, textDiscription,
                                    tableDiscription, tableIndexDiscription)
                except Exception as ex:
                    pass
            elif contentRow["type"] == "chart" or contentRow["type"] == "wordchart":
                try:
                    wordcharts(documentDocx, contentRow, json_data, chartfile, replaceChart)
                except Exception as ex:
                    pass
            elif contentRow["type"] == "table":
                try:
                    wordtable(documentDocx, contentRow, json_data, tableHead)
                except Exception as ex:
                    pass
            else:
                pass
        worddiscriptionReplace(documentDocx)
    except Exception as ex:
        pass
    finally:
        #lock.release()
        pass
    return None


def check_json_format(raw_msg):
    if isinstance(raw_msg, str):
        try:
            json.loads(raw_msg)
            for key, value in json.loads(str(raw_msg).strip()).items():
                return True
        except Exception as e:
            pass
        return False
    else:
        return False


class myCalculation:
    def __init__(self):
        self._obj_mul = re.compile(r"(-?\d+\.?\d*)\*(-?\d+\.?\d*)")  # 乘法
        self._obj_div = re.compile(r"(-?\d+\.?\d*)/(-?\d+\.?\d*)")  # 除法
        self._obj_add = re.compile(r"(-?\d+\.?\d*)\+(-?\d+\.?\d*)")  # 加法
        self._obj_sub = re.compile(r"(-?\d+\.?\d*)-(-?\d+\.?\d*)")  # 减法
        self._obj_f = re.compile(r"\(?\+?-?\d+\)?")  # 检查括号内是否运算完毕规则
        self._obj_k = re.compile(r"\([^()]+\)")  # 寻找最内层括号规则
        self._obj_che = re.compile(r"[^0-9+\-*/()\s.]")  # 匹配输入非法字符
        self._PREC = '{:+.15f}'  # 计算精度 15代表15位小数

    def count(self, calculation):
        """
         计算没有括号的式子
        :type calculation: object
        :return:
        """
        calculationString = self.rm_SP(calculation)
        while True:
            if self._obj_div.search(calculationString):  # 除法(必须先判断)
                exp = re.split(r'/', self._obj_div.search(calculationString).group())
                answer = float(exp[0]) / float(exp[1])
                calculationString = self._obj_div.sub(self._PREC.format(answer), calculationString, 1)
            elif self._obj_mul.search(calculationString):  # 乘法
                exp = re.split(r'\*', self._obj_mul.search(calculationString).group())
                answer = float(exp[0]) * float(exp[1])
                calculationString = self._obj_mul.sub(self._PREC.format(answer), calculationString, 1)
            elif self._obj_add.search(calculationString):  # 加法
                exp = re.split(r'\+', self._obj_add.search(calculationString).group())
                answer = float(exp[0]) + float(exp[1])
                calculationString = self._obj_add.sub(self._PREC.format(answer), calculationString, 1)
            elif self._obj_sub.search(calculationString):  # 减法
                exp = re.split(r'-', self._obj_sub.search(calculationString).group())
                if exp[0] == "":  # 前面有负号的时候
                    answer = 0 - float(exp[1]) - float(exp[2])
                    calculationString = self._obj_sub.sub(self._PREC.format(answer), calculationString, 1)
                else:
                    answer = float(exp[0]) - float(exp[1])
                    calculationString = self._obj_sub.sub(self._PREC.format(answer), calculationString, 1)
            elif self._obj_f.search(calculationString):  # 结束循环
                calculationString = re.sub('\(|\)|', '', calculationString)
                return calculationString
            calculationString = self.rm_SP(calculationString)  # 去除多余的符号

    @staticmethod
    def rm_SP(calculationString):
        """
        去除符号
        :param calculationString:
        :return:
        """
        calculationString = re.sub('\+\+','+',calculationString)
        calculationString = re.sub('--', '+', calculationString)
        calculationString = re.sub('\+-', '-', calculationString)
        calculationString = re.sub('-\+', '-', calculationString)
        calculationString = re.sub('/\+', '/', calculationString)
        calculationString = re.sub('\*\+', '*', calculationString)
        calculationString = re.sub('^\+', '', calculationString)
        return calculationString

    def rm_PAR(self, calculationString):
        """
        计算括号里
        :param calculationString:
        :return:
        """
        calculationString = self.rm_SP(calculationString)
        list_m = self._obj_k.findall(calculationString)
        list_map = map(self.count, list_m)
        for i in range(len(list_m)):
            calculationString = calculationString.replace(list_m[i], list_map.__next__(), 1)
        return calculationString

    def main(self, calculationString):
        """
        主函数，循环计算
        :param calculationString:
        :return
        """
        if self.checkout(calculationString):
            calculationString = re.sub('\s', '', calculationString)  # 去掉空格
            while True:
                if self._obj_k.search(calculationString):  # 是否还存在括号
                    calculationString = self.rm_PAR(calculationString)
                    continue
                answer = self.count(calculationString)
                return answer
        return ""

    def checkout(self, calculationString):
        """
        校验输入是否合法
        :param calculationString:
        :return
        """
        if len(re.findall('\(', calculationString)) != len(re.findall('\)', calculationString)):
            return False
        elif not (isinstance(self._obj_che.findall(calculationString), list) and
                  len(self._obj_che.findall(calculationString))) == 0:
            return False
        return True


if __name__ == '__main__':
    PlatID = "1"
    #ProjID = "1"
    #mongodb_cfg = 'readInfo'
    #templateFileServerUrl = ""
    nacos_main()
    ProjID = ""     #"6268a6f79651d75b007e9c10"
    mongodb_cfg, maxResponseCount,templateFileServerUrl = nacos_py('192.168.2.160:3000')
    #ProjID = "627ba5caf04f201d935fd304"
    #PlatID = ""
    #mongodb_cfg,maxResponseCount = nacos_py('medudata.bjmu.edu.cn')
    TokenID = ""
    #TempID = "5ee1b6cc223bbe2bfbc96ec7"
    #fileGroup = ["上海交通大学", "上海健康医学院", "中南大学", "中国医科大学", "中山大学"]
    #fileGroup = ["兰州大学"]
    #fileName = "-全国医学教育发展中心2020CMSS报告"
    #caseFilter = "P0Q2"
    #for fileItem in fileGroup:
        #NewFileName = fileItem + '-全国医学教育发展中心2020CMSS报告'
        #CasesCondition = dict(P0Q2=fileItem)
        #data = myReportCreate(PlatID, ProjID, TempID, NewFileName, CasesCondition)
    #fileGroup = ["北京工业大学"]
    #TempID = "5ee1f95cc30f48b41cb3610b"
    #fileName = "毕业生就业状况调查统计报告"
    #caseFilter = "zkeyUserInfoSYXMC"
    #data = myReportCreate(PlatID, ProjID, TempID, NewFileName, CasesCondition)
    #湖北医药学院    5年制5年级
    """
    TempID = "5f4773a911aaf29d30dace9b"
    fileGroup = ["同济大学"]
    fileName = "2021年度临床医学专业（本科）水平测试成绩分析报告"
    caseFilter = "学校名称"
    edition = ""
    """
    """
    TempID = "5ed89e3dd714d125jdbg2021"
    fileName = "毕业生就业状况调查统计报告"
    caseFilter = "YXMC"
    fileGroup = ["北京电子科技职业学院"]
    CasesCondition = None
    
    fileGroup = ["北方工业大学","北京服装学院","北京工商大学","北京工业大学","北京建筑大学","北京交通大学","北京师范大学",
                 "北京石油化工学院","北京体育大学","北京信息科技大学","北京印刷学院","北京中医药大学","首都体育学院","中央美术学院",
                 "中央民族大学","北京城市学院","北京电影学院","北京联合大学","北京农学院","首都师范大学"]"""
    #edition = "专科派遣库"
    """fileGroup = ["北京大学","北京化工大学","北京理工大学","北京外国语大学","北京物资学院","北京语言大学","对外经济贸易大学",
                 "首都经济贸易大学","中国地质大学（北京）","中国石油大学（北京）","中国戏曲学院","中国音乐学院"]"""
    #edition = "专本研创人"
    """fileGroup = ["北京第二外国语学院","北京科技大学","北京林业大学","北京舞蹈学院","北京协和医学院（清华大学医学部）","北京邮电大学",
                 "华北电力大学","外交学院","中国科学院大学","中国矿业大学（北京）","中国农业大学","中国青年政治学院","中国人民大学",
                 "中国人民公安大学","中国社会科学院大学","中国政法大学","中央财经大学","中央音乐学院","首都医科大学","中国传媒大学"]"""
    #edition = "专本研"
    """fileGroup = ["北京财贸职业学院","北京电子科技职业学院","北京工业职业技术学院","北京吉利学院","北京经济管理职业学院","北京农业职业学院",
                 "北京培黎职业学院","北京信息职业技术学院","北京政法职业学院"]"""
    #edition = "专创"
    """fileGroup = ["北京北大方正软件职业技术学院","北京汇佳职业学院","北京交通运输职业学院","北京经贸职业学院","北京劳动保障职业学院",
                 "北京青年政治学院","北京网络职业学院"]
    edition = "专创人"""
    """fileGroup = ["北京交通职业技术学院","北京京北职业技术学院","北京经济技术职业学院","北京科技职业学院","北京社会管理职业学院",
                 "北京体育职业学院","北京卫生职业学院","北京戏曲艺术职业学院","北京艺术传媒职业学院","首都经济贸易大学密云分校",
                 "首钢工学院","中国劳动关系学院"]"""
    #edition = "专"
    """fileGroup = ["中央戏剧学院", "首都师范大学科德学院", "中华女子学院"]"""
    #edition = "本"
    """fileGroup = ["北京工业大学耿丹学院", "北京邮电大学世纪学院"]
    edition = "本创"""
    """
    fileGroup = ["北京第二外国语学院中瑞酒店管理学院"]
    edition = "本创人"
    """
    """
    #TempID = "5ee1b6cc223bbe2blcyx2021"
    TempID = "5ee1b6cc223bbe2blcyj2021"
    fileName = "-全国医学教育发展中心2021临床药学专业CMSS报告"
    caseFilter = "XXMC"
    
    fileGroup = ["中国药科大学","内蒙古医科大学","南昌大学","哈尔滨医科大学","四川大学","大理大学","天津中医药大学",
                 "天津医科大学","宁夏医科大学","山东第一医科大学","山西医科大学","广东医科大学","广州医科大学",
                 "广西医科大学","徐州医科大学","新乡医学院","新疆医科大学","昆明医科大学","桂林医学院","沈阳药科大学",
                 "河南大学","济宁医学院","海南医学院","温州医科大学","皖南医学院","石河子大学","福建医科大学","遵义医科大学",
                 "重庆医科大学","首都医科大学","中国医科大学","南京医科大学","河北医科大学","湖北科技学院","西南医科大学",
                 "兰州大学","大连医科大学","山东大学","齐齐哈尔医学院","中南大学","贵州医科大学","安徽医科大学","潍坊医学院","南方医科大学"]
    
    #fileGroup = ["北京大学"]
    CasesCondition = {"category": "临床药学专业"}
    edition = "药学"
"""
    """
    TempID = "5ed89e3dd714d125hzbg2021"
    fileName = "2021届毕业生就业质量报告"
    caseFilter = "YXMC"
    CasesCondition = None
    #fileGroup = ["北京工业大学","中国音乐学院", "中央音乐学院"]
    #edition = "整体本研"
    #edition = "石油"
    #fileGroup = ["中央美术学院","中央音乐学院"]
    #edition = "本硕博"
    #fileGroup = ["北京劳动保障职业学院","北京农业职业学院","北京政法职业学院"]
    #edition = "专科"
    #fileGroup = ["北京外国语大学"]
    #edition = "派遣库"
    #fileGroup = ["北京工业大学","北方工业大学"]
    edition = "专科"
    # fileGroup = ["北方工业大学","北京工商大学","北京服装学院","北京印刷学院","北京建筑大学","北京农学院",
    #             "首都体育学院","北京第二外国语大学","中国音乐学院","中国戏曲学院","北京电影学院","北京舞蹈学院",
    #             "北京工业大学","北京化工大学","北京中医药大学","首都师范大学","北京外国语大学","中央音乐学院",
    #             "中央美术学院","中央民族大学","中国石油大学（北京）","中国地质大学（北京）","中国政法大学",
    #             "北京语言大学","中国传媒大学", "首都医科大学"]
    fileGroup = ["北京信息职业技术学院"]
    #edition = "院系"
    #fileGroup = ["北京工业职业技术学院"]
    #edition = "校园渠道"

    
    TempID = "5ed89e3dd714d125yxbg2021"
    fileName = "2021北京工商大学院系报告_XXX"
    caseFilter = "SZYX"
    CasesCondition = None
    edition = "北工商"
    #fileGroup = ["2食品与健康学院","3轻工科学技术学院","4化学与材料工程学院","5生态环境学院",
    #             "6人工智能学院","7计算机学院","8经济学院","9商学院",
    #             "11电商与物流学院","12法学院","14外国语学院","15传媒与设计学院","13马克思主义学院"]
    fileGroup = ["1数学与统计学院"]
 
    TempID = "5ed89e3dd714d125hzdw2021"
    fileName = "2021届毕业生就业质量报告用人单位"
    caseFilter = "YXMC"
    CasesCondition = None
    edition = ""
    #fileGroup = ["北京服装学院", "北京化工大学", "北京中医药大学", "北京外国语大学", "北京电影学院",
    #             "北京工商大学", "中央音乐学院"]
    fileGroup = ["北京信息职业技术学院"]
  """
    """
    TempID = "5ee1f95cc30f48b4rgzn2021"
    fileName = "中小学人工智能赋能教育应用现状及课程实施调查报告（教师篇）"
    caseFilter = "Analyze"
    CasesCondition = None
    edition = ""
    fileGroup = ["安徽省芜湖市","黑龙江省","吉林省","江苏省南通市","辽宁省","宁夏回族自治区",
                 "山西省运城市","上海市市辖区宝山区","四川省","河南省"]
    
    TempID = "5ee1f95cc30f48xsrgzn2021"
    fileName = "中小学人工智能赋能教育应用现状及课程实施调查报告（学生篇）"
    caseFilter = "Analyze"
    CasesCondition = None
    edition = ""
    fileGroup = ["安徽省芜湖市","黑龙江省","吉林省","江苏省南通市","辽宁省","宁夏回族自治区","山西省运城市",
                 "上海市宝山区","四川省","河南省","河北省唐山市开平区"]
        TempID = "5ee1b6cc223bbe2blhjt2021"
        fileName = "2021年度联泓新材料科技股份有限公司个人绩效考核综合评价报告——XXX"
        caseFilter = "姓名"
        CasesCondition = None
        edition = ""
        fileGroup = ["杨公政","陈中亭","孙利"]
"""
    """
    TempID = "5ed89e3dd714d125hzfb2021"
    fileName = "附表"
    caseFilter = "YXMC"
    CasesCondition = None
    edition = "专科"
    #fileGroup = ["北方工业大学","北京工商大学","北京服装学院","北京印刷学院","北京建筑大学","北京农学院",
    #             "首都体育学院","北京第二外国语大学","中国音乐学院","中国戏曲学院","北京电影学院","北京舞蹈学院",
    #             "北京工业大学","北京化工大学","北京中医药大学","首都师范大学","北京外国语大学","中央音乐学院",
    #             "中央美术学院","中央民族大学","中国石油大学（北京）","中国地质大学（北京）","中国政法大学",
    #             "北京语言大学","中国传媒大学", "首都医科大学"]
    #fileGroup = ["北京工业职业技术学院", "北京信息职业技术学院", "北京电子科技职业学院", "北京青年政治学院",
    #             "北京农业职业学院", "北京财贸职业学院", "北京劳动保障职业学院",
    #             "北京社会管理职业学院", "北京政法职业学院", "首都医科大学", "北京舞蹈学院","北京舞蹈学院研"]
    fileGroup = ["北京信息职业技术学院"]
   
    TempID = "5ee1f95cc30f48bhljrc2021"
    fileName = "黑龙江省普通高校人才工作现状调查（XXX）"
    caseFilter = "school"
    CasesCondition = None
    edition = "民办"
    fileGroup = ["哈尔滨北方航空职业技术学院","哈尔滨城市职业学院","哈尔滨传媒职业学院","哈尔滨广厦学院","哈尔滨华德学院",
                 "哈尔滨剑桥学院","哈尔滨石油学院","哈尔滨信息工程学院","哈尔滨应用职业技术学院","哈尔滨远东理工学院",
                 "黑龙江财经学院","黑龙江东方学院","黑龙江工程学院昆仑旅游学院","黑龙江工商学院","黑龙江三江美术职业学院",
                 "黑龙江外国语学院","齐齐哈尔工程学院","齐齐哈尔理工职业学院"]
   
   TempID = "5ee1b6cc223bbecmssxs2021"
    fileName = "-全国医学教育发展中心2021新生基线调查报告"    
    caseFilter = "XXMC"
    CasesCondition = None
    edition = ""
    fileGroup = ["三峡大学", "上海杉达学院", "东南大学"]
    fileGroup = ["三峡大学", "上海中医药大学", "上海交通大学", "上海健康医学院", "上海杉达学院", "东南大学",
                 "中南大学", "中国医科大学", "中国药科大学", "中山大学", "中山大学南方学院", "中山大学新华学院",
                 "丽江文化旅游学院", "九江学院", "佳木斯大学", "兰州大学", "内蒙古民族大学", "内蒙古科技大学",
                 "北京中医药大学", "北京协和医学院", "北京大学", "北华大学", "华中科技大学", "华北理工大学",
                 "南京医科大学", "南华大学", "南开大学", "南方医科大学", "南昌大学", "南通大学", "南通大学杏林学院", "厦门大学",
                 "台州学院", "右江民族医学院", "吉林医药学院", "吉林大学", "吉首大学张家界学院", "哈尔滨医科大学", "嘉兴学院",
                 "嘉应学院", "四川大学", "复旦大学", "大连医科大学", "大连大学", "天津中医药大学", "天津医科大学", "宁夏医科大学",
                 "宁波大学", "安康学院", "安徽三联学院", "安徽医科大学", "安徽理工大学", "宜春学院", "山东大学", "山东石油化工学院",
                 "山东第一医科大学", "山西医科大学", "山西大同大学", "川北医学院", "常州大学", "广东医科大学", "广东药科大学",
                 "广州医科大学", "广西中医药大学", "广西医科大学", "广西科技大学", "延边大学", "成都中医药大学", "成都医学院",
                 "成都大学", "扬州大学", "承德医学院", "攀枝花学院", "新乡医学院", "新余学院", "新疆医科大学", "昆明医科大学",
                 "昆明学院", "昆明理工大学", "暨南大学", "桂林医学院", "武汉科技大学", "汕头大学", "江南大学", "沈阳药科大学",
                 "河北医科大学", "河北工程大学", "河南大学", "河南科技大学", "浙大城市学院", "浙江大学", "深圳大学", "清华大学",
                 "温州医科大学", "湖北中医药大学", "湖北科技学院", "湖南中医药大学", "湖南医药学院", "湖州师范学院", "潍坊医学院",
                 "牡丹江医学院", "甘肃中医药大学", "皖南医学院", "石河子大学", "福建医科大学", "绍兴文理学院", "绍兴文理学院元培学院",
                 "苏州大学", "莆田学院", "蚌埠医学院", "西北民族大学", "西南医科大学", "西安交通大学", "西安交通大学城市学院",
                 "西安翻译学院", "贵州中医药大学", "贵州医科大学", "赤峰学院", "辽宁中医药大学", "辽宁何氏医学院", "重庆医科大学",
                 "锦州医科大学", "长春中医药大学", "长江大学", "长沙医学院", "长治医学院", "青岛大学", "青岛滨海学院", "青海大学",
                 "首都医科大学", "黄河科技学院", "黑龙江中医药大学", "齐鲁医药学院", "齐齐哈尔医学院", "齐齐哈尔工程学院"]             
    TempID = "5ee1fjpjs0f48stucity2021"
    fileName = "2021年福建省义务教育质量监测报告（XXX）（科学）"
    caseFilter = "city"
    CasesCondition = None
    edition = "科学"
    fileGroup = ["81", "82", "83", "84", "85", "86", "87", "88", "89"]
    TempID = "5ee1fjpjs0f48studist2021"
    fileName = "2021年福建省义务教育质量监测报告（XXX）"
    caseFilter = "dist"
    CasesCondition = None
    edition = ""
    fileGroup = ["810101","810102","810103","810104","810108","810109","810110","810113","820202","820203","820206",
                 "830302","830303","830304","830305","840401","840402","840403","840408","840409","840412","850501",
                 "850502","850503","850508","850511","850513","850514","860602","860603","860604","860605","860608",
                 "860611","870703","870705","870707","870708","870710","880803","880805","880806","890901","890903",
                 "890906","890908","911001"]
    
    TempID = "5ee1fjpjs0f48zhtcity2021"
    fileName = "2021年福建省义务教育质量监测专题报告（XXX）"
    caseFilter = "city"
    CasesCondition = None
    edition = ""
    fileGroup = ["81"]
    
    TempID = "5ee1fjpjs0f48zhtdist2021"
    fileName = "2021年福建省义务教育质量监测专题报告（XXX）"
    caseFilter = "dist"
    CasesCondition = None
    edition = ""
    fileGroup = ["810101"]
    
    TempID = "5ee1fjpjs0f48zhtschl2021"
    fileName = "2021年福建省义务教育质量监测专题报告（XXX）"
    caseFilter = "SchID"
    CasesCondition = None
    edition = "福州实小"
    fileGroup = ["810101403"]
    
    TempID = "626b94d601bbf65fef5c1fbe"
    TempID = "627ba654a517907d77fdaf91"
    fileName = "-全国医学教育发展中心2021新生基线调查报告"
    caseFilter = "XXMC"
    CasesCondition = None
    edition = "测试文件"
    fileGroup = ["三峡大学"]
    
     TempID = "62bacd09488ddb5cad7fbd06"
    fileName = "XXX"
    caseFilter = "SCHOOLDM"
    edition = "报告"
    CasesCondition = {"TYPE":"1.0"}
    fileGroup = ['1013.0']
    
    TempID = "62e0f087e401636a5ba0d7db"
    fileName = "毕业生就业状况调查统计报告"
    caseFilter = "YXMC"
    edition = "报告"
    CasesCondition = None
    fileGroup = ['北京工业大学']
    
    TempID = "6311b602421ec53a6020c348"
    fileName = "2022届毕业生就业质量报告"
    caseFilter = "YXMC"
    edition = "2022届毕业生就业质量报告模板-蓝色"
    CasesCondition = None
    fileGroup = ['中国政法大学']
    """

    TempID = "62ecc6046ccb21182770a066"
    fileName = "中国中小学教育数字化转型调研报告（校长篇）_全国"
    caseFilter = "alldata"
    edition = "数字化转型调查（校长篇）定稿8.12"
    CasesCondition = None
    fileGroup = ['1']

    updateFlag = False
    myReportMainJava(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup, fileName, edition,
                     updateFlag, templateFileServerUrl, CasesCondition)
    print("报告生成完成！")
    #for fileItem in fileGroup:
        #NewFileName = fileItem + '2020年度临床医学专业（本科）水平测试成绩分析报告'
        #CasesCondition = dict(学校名称=fileItem)
        #data = myReportCreate(PlatID, ProjID, TempID, NewFileName, CasesCondition)