package nckd.jxccl.opmc.pm.plugin.form;

import com.google.common.collect.Lists;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.exception.KDBizException;
import kd.bos.fileservice.FileItem;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.MessageTypes;
import kd.bos.form.control.Control;
import kd.bos.form.control.Image;
import kd.bos.form.control.Label;
import kd.bos.form.control.events.UploadEvent;
import kd.bos.form.control.events.UploadListener;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.impt.ExcelReader;
import kd.bos.impt.SheetHandler;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
import kd.bos.url.UrlService;
import kd.bos.util.FileNameUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jetbrains.annotations.NotNull;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName: ImportKPISelectFormPlugin
 * @Description: 绩效结果导入模板选择界面表单插件
 * @Author: PJJ
 * @Date: 2026/1/7 上午10:24
 * @Version: 1.0
 */
public class ImportKPISelectFormPlugin extends AbstractFormPlugin implements UploadListener {
    private static final Log logger = LogFactory.getLog(ImportKPISelectFormPlugin.class);

    @Override
    public void afterBindData(EventObject e) {
        super.afterBindData(e);
        this.getView().setVisible(false, "nckd_filepanel");
        this.getView().setVisible(true, "nckd_uploadpanel");
    }

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addClickListeners("nckd_btndownload", "nckd_btnresetfile", "btnok");
        Image img = this.getControl("nckd_btnupload");
        img.addUploadListener(this);
        Label label = this.getControl("nckd_labelap3");
        label.addUploadListener(this);
    }

    @Override
    public void click(EventObject evt) {
        super.click(evt);
        String key = ((Control) evt.getSource()).getKey();
        switch (key) {
            case "nckd_btndownload":
                //模板下载
                downloadExcel();
                break;
            case "nckd_btnresetfile":
                //删除文件
                this.deleteTemplateFile();
                break;
            case "btnok":
                //回传数据
                this.importData();

                break;
            default:
                break;

        }
    }

    @Override
    public void upload(UploadEvent evt) {
        UploadListener.super.upload(evt);
        Object[] urls = evt.getUrls();
        if (urls.length > 0) {
            IFormView view = this.getView();
            String url = (String) urls[0];
            view.setVisible(true, "nckd_filepanel");
            view.setVisible(false, "nckd_uploadpanel");
            IDataModel model = this.getModel();
            model.setValue("nckd_filename", url.substring(url.lastIndexOf(47) + 1));
            String fullUrl = UrlService.getAttachmentFullUrl(url);
            model.setValue("nckd_filepath", url);
            model.setValue("nckd_fullpath", fullUrl);
        }
    }

    private void deleteTemplateFile() {
        this.getModel().setValue("nckd_filename", "");
        this.getModel().setValue("nckd_filepath", "");
        this.getView().setVisible(false, "nckd_filepanel");
        this.getView().setVisible(true, "nckd_uploadpanel");
    }

    private void importData() {
        String url = this.getModel().getDataEntity().getString("nckd_filepath");
        FormShowParameter params = this.getView().getFormShowParameter();
        //导入任务id
//        Long importPlanId = params.getCustomParam("importplan");
        //导入模板id
        Long templateId = params.getCustomParam("template");
        //绩效导入模板
        DynamicObject template = BusinessDataServiceHelper.loadSingle(templateId, "nckd_import_kpi_template");
        DynamicObjectCollection entry = template.getDynamicObjectCollection("nckd_outimptplentry");
//        //绩效导入任务
//        DynamicObject importPlan = BusinessDataServiceHelper.loadSingle(importPlanId, "nckd_importplan");
        if (StringUtils.isBlank(url)) {
            this.getView().showErrorNotification(ResManager.loadKDString("请先上传数据文件后操作。", "ImportKPISelectFormPlugin_1", "opmc-formplugin", new Object[0]));
        } else {
            try {
//                HashMap<String, List<Map<Integer, String>>> returnMap = new HashMap<>();
                //编码集合
                List<Map<Integer, String>> dataHeadNumberList = new ArrayList<>();
                //名称集合
                List<Map<Integer, String>> dataHeadList = new ArrayList<>();
                //数据集合
                List<Map<Integer, String>> dataRowList = new ArrayList<>();
                readExcel(url, dataHeadList, dataRowList, dataHeadNumberList);
                //校验导入模板
                String templateMsg = checkExcelTemplate(dataHeadList, entry, dataHeadNumberList);
                //校验数据必录
                String DataMsg = checkExcelMustInputData(dataHeadList, dataRowList);
                String errMsg = templateMsg + "\n" + DataMsg;
                if (!StringUtils.isNotBlank(errMsg)) {
//                    returnMap.put("dataHeadNumberList", dataHeadNumberList);
//                    returnMap.put("dataHeadList", dataHeadList);
//                    returnMap.put("dataRowList", dataRowList);
                    //写入数据
                    Boolean b = saveData(dataHeadNumberList, dataRowList);
                    if (b) {
                        this.getView().returnDataToParent(true);
                        this.getView().close();
                    } else {
                        this.getView().showTipNotification("数据保存错误请联系管理员!");
                    }
                } else {
                    this.getView().showTipNotification(errMsg);
                }
            } catch (Exception e) {
                String msg = ResManager.loadKDString("excel解析错误!", "ImportKPISelectFormPlugin_2", "opmc-formplugin", new Object[0]);
                this.getView().showMessage(msg, e.getMessage(), MessageTypes.Default);
            }
        }
    }

    private String judgeDataType(Object object) {
        if (object instanceof Boolean) {
            Boolean b = (Boolean) object;
            return b ? "是" : "否";
        } else if (object instanceof Date) {
            SimpleDateFormat basicFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = basicFormat.format((Date) object);
            return date;
        } else if (object instanceof BigDecimal) {
            return ((BigDecimal) object).toString();
        }
        return (String) object;
    }

    private Boolean saveData(List<Map<Integer, String>> dataHeadNumberList, List<Map<Integer, String>> dataRowList) {
        QFilter commonQFilter = new QFilter("enable", QCP.equals, "1");
        commonQFilter.and("status", QCP.equals, "C");
        //表头编码
        Map<Integer, String> zeroExcelRow = dataHeadNumberList.get(0);
        QFilter dimensionQFilter = new QFilter("number", QCP.in, zeroExcelRow.values());
        //查询绩效导入任务
        DynamicObject importPlan = BusinessDataServiceHelper.loadSingle(this.getView().getFormShowParameter().getCustomParam("importplan"), "nckd_importplan");
        //考核维度项目
        DynamicObject[] examineDimension = BusinessDataServiceHelper.load("nckd_examine_dimension", "id,number,name", new QFilter[]{dimensionQFilter, commonQFilter});
        Map<String, DynamicObject> examineDimensionMap = Arrays.stream(examineDimension).collect(Collectors.toMap(i -> i.getString("number"), i -> i));

        //汇总员工工号
        List<String> userNumbers = dataRowList.stream().map(i -> i.get(1)).collect(Collectors.toList());
        QFilter userQFilter = new QFilter("number", QCP.in, userNumbers);
        DynamicObject[] users = BusinessDataServiceHelper.load("bos_user", "id,name,number", new QFilter[]{userQFilter, commonQFilter});
        Map<String, DynamicObject> userMap = Arrays.stream(users).collect(Collectors.toMap(i -> i.getString("number"), i -> i, (existing, replacement) -> existing));

        //汇总组织编码
        List<String> deptNumbers = dataRowList.stream().map(i -> i.get(3)).collect(Collectors.toList());
        QFilter deptQFilter = new QFilter("number", QCP.in, deptNumbers);
        DynamicObject[] depts = BusinessDataServiceHelper.load("bos_org", "id,name,number", new QFilter[]{deptQFilter, commonQFilter});
        Map<String, DynamicObject> deptMap = Arrays.stream(depts).collect(Collectors.toMap(i -> i.getString("number"), i -> i, (existing, replacement) -> existing));

        //汇总岗位编码
        List<String> postNumbers = dataRowList.stream().map(i -> i.get(5)).collect(Collectors.toList());
        QFilter postQFilter = new QFilter("number", QCP.in, postNumbers);
        DynamicObject[] posts = BusinessDataServiceHelper.load("bos_position", "id,name,number", new QFilter[]{postQFilter, commonQFilter});
        Map<String, DynamicObject> postMap = Arrays.stream(posts).collect(Collectors.toMap(i -> i.getString("number"), i -> i, (existing, replacement) -> existing));

        //查询绩效绩效结果-后续计算部门累计平均排名
        HashMap<String, List<String>> userHistoryRank = new HashMap<>();
        DynamicObject[] examinProjectResult = BusinessDataServiceHelper.load("nckd_examinproject_result", "nckd_entryentity.nckd_examine_dimension,nckd_entryentity.nckd_result,nckd_org,nckd_user", new QFilter[]{new QFilter("nckd_user.number", QCP.in, userNumbers)});
        for (DynamicObject object : examinProjectResult) {
            //用户
            DynamicObject user = object.getDynamicObject("nckd_user");
            String userNumber = user.getString("number");
            for (DynamicObject entry : object.getDynamicObjectCollection("nckd_entryentity")) {
                //分录项目类型
                DynamicObject dimension = entry.getDynamicObject("nckd_examine_dimension");
                String dimensionNumber = dimension.getString("number");
                ArrayList<String> rank = new ArrayList<>();
                //判断是否排名
                if (StringUtils.equals(dimensionNumber, "JT-00012")) {
                    //添加历史成绩
                    rank.add(entry.getString("nckd_result"));
                }
                userHistoryRank.put(userNumber, rank);
            }

        }
        //添加更新逻辑
        DynamicObject[] load = BusinessDataServiceHelper.load("nckd_examinproject_result", "nckd_user,nckd_rank_org,nckd_remark,nckd_cumulativeranking,nckd_rank_org,nckd_postbase,nckd_entryentity.nckd_examine_dimension,nckd_entryentity.nckd_result", new QFilter[]{new QFilter("nckd_importplan.id", QCP.equals, this.getView().getFormShowParameter().getCustomParam("importplan"))});
        List<String> collect = Arrays.stream(load).map(i -> i.getString("nckd_user.number")).collect(Collectors.toList());
        //1为姓名 3 为组织 5为岗位 6为排名单位 17为备注 12 为部门累计平均排名
        ArrayList<DynamicObject> saveList = new ArrayList<>();
        for (Map<Integer, String> integerStringMap : dataRowList) {
            String userNumber = integerStringMap.get(1);
            for (DynamicObject billData : load) {
                String string = billData.getString("nckd_user.number");
                //先判断excel行和当前绩效导入结果数据是否同一条
                if (StringUtils.equals(string, userNumber)) {
                    //后判断为新增还是修改
                    if (!collect.contains(userNumber)) {
                        //添加数据
//                        addResultData(saveList, integerStringMap, importPlan, examineDimensionMap, userMap, deptMap, postMap, zeroExcelRow, userHistoryRank);
                    } else {
                        //更新数据
                        updateResultData(billData, saveList, integerStringMap, examineDimensionMap, zeroExcelRow, userHistoryRank);
                    }
                }
            }
        }
        Object[] save = SaveServiceHelper.save(saveList.toArray(new DynamicObject[0]));
        if (ObjectUtils.isNotEmpty(save)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 添加绩效导入结果新数据
     * @param saveList 保存用
     * @param integerStringMap 表格行数据
     * @param examineDimensionMap 考核维度基础资料
     * @param zeroExcelRow 表头行
     * @param userHistoryRank 历史排名
     */
    private void updateResultData(DynamicObject resultData,
                                  ArrayList<DynamicObject> saveList,
                                  Map<Integer, String> integerStringMap,
                                  Map<String, DynamicObject> examineDimensionMap,
                                  Map<Integer, String> zeroExcelRow,
                                  HashMap<String, List<String>> userHistoryRank) {
        //排名单位
        resultData.set("nckd_rank_org", integerStringMap.get(6));
        //备注
        resultData.set("nckd_remark", integerStringMap.get(17));
        DynamicObjectCollection entry = resultData.getDynamicObjectCollection("nckd_entryentity");
        //清空数据
        entry.clear();
        //重新添加
        addEntryData(resultData, entry, integerStringMap, examineDimensionMap, zeroExcelRow, userHistoryRank);
        saveList.add(resultData);
    }

    /**
     * 添加绩效导入结果新数据
     * @param saveList 保存用
     * @param integerStringMap 表格行数据
     * @param importPlan 导入任务
     * @param examineDimensionMap 考核维度基础资料
     * @param userMap 用户
     * @param deptMap 部门
     * @param postMap 岗位
     * @param zeroExcelRow 表头行
     * @param userHistoryRank 历史排名
     */
    private void addResultData(ArrayList<DynamicObject> saveList,
                               Map<Integer, String> integerStringMap,
                               DynamicObject importPlan,
                               Map<String, DynamicObject> examineDimensionMap,
                               Map<String, DynamicObject> userMap,
                               Map<String, DynamicObject> deptMap,
                               Map<String, DynamicObject> postMap,
                               Map<Integer, String> zeroExcelRow,
                               HashMap<String, List<String>> userHistoryRank) {
        DynamicObject newData = BusinessDataServiceHelper.newDynamicObject("nckd_examinproject_result");
        //设置默认数据
        newData.set("enable", "1");
        newData.set("status", "A");
        newData.set("nckd_importplan", importPlan);
        //姓名
        newData.set("nckd_user", userMap.get(integerStringMap.get(1)));
        //行政组织
        newData.set("nckd_org", deptMap.get(integerStringMap.get(3)));
        newData.set("group", deptMap.get(integerStringMap.get(3)));
        //岗位
        newData.set("nckd_postbase", postMap.get(integerStringMap.get(5)));
        //排名单位
        newData.set("nckd_rank_org", integerStringMap.get(6));
        //备注
        newData.set("nckd_remark", integerStringMap.get(17));

        //增加分录数据
        DynamicObjectCollection entry = newData.getDynamicObjectCollection("nckd_entryentity");
        addEntryData(newData, entry, integerStringMap, examineDimensionMap, zeroExcelRow, userHistoryRank);
        saveList.add(newData);
    }

    /**
     * 添加分录数据
     * @param billData 绩效导入结果
     * @param entry 分录
     * @param integerStringMap 表格行
     * @param examineDimensionMap 考核维度数据
     * @param zeroExcelRow 表头行
     * @param userHistoryRank 历史排名
     */
    private void addEntryData(DynamicObject billData,
                              DynamicObjectCollection entry,
                              Map<Integer, String> integerStringMap,
                              Map<String, DynamicObject> examineDimensionMap,
                              Map<Integer, String> zeroExcelRow,
                              HashMap<String, List<String>> userHistoryRank) {
        for (Integer i : integerStringMap.keySet()) {
            //除1为姓名 3为组织 5为岗位 6为排名单位 17为备注 12 为部门累计平均排名外全部存入分录
            if (i != 0 && i != 1 && i != 2 && i != 3 && i != 4 && i != 5 && i != 6 && i != 17) {
                DynamicObject entryRow = entry.addNew();
                entryRow.set("nckd_examine_dimension", examineDimensionMap.get(zeroExcelRow.get(i)));
                entryRow.set("nckd_result", integerStringMap.get(i));
            }
            //计算部门累计平均排名
            if (i == 12) {
                //本次导入排名
                String rank = integerStringMap.get(11);
                //用户历史数据排名
                List<String> userHistory = userHistoryRank.get(integerStringMap.get(1));
                if (ObjectUtils.isNotEmpty(userHistory)) {
                    //计算
                    int sum = userHistory.stream().mapToInt(Integer::parseInt).sum();
                    sum += Integer.parseInt(rank);
                    int finalRank = sum / (userHistory.size() + 1);
                    billData.set("nckd_cumulativeranking", finalRank);
                } else {
                    billData.set("nckd_cumulativeranking", Integer.parseInt(rank));
                }
            }
        }
    }

    /**
     * 校验导入模板
     * @param dataHeadList 模板表头数据
     * @param entry 导入模板基础资料分录数据
     * @return 错误提示
     */
    @NotNull
    private String checkExcelTemplate(List<Map<Integer, String>> dataHeadList, DynamicObjectCollection entry, List<Map<Integer, String>> dataHeadNumberList) {
        //根据导入模板基础资料 判断excel表格表头数据是否正确
        List<String> unMustInputRowData = entry.stream().filter(i -> !i.getBoolean("nckd_mustinput")).map(i -> i.getString("nckd_examinename")).collect(Collectors.toList());
        List<String> mustInputRowData = entry.stream().filter(i -> i.getBoolean("nckd_mustinput")).map(i -> "*" + i.getString("nckd_examinename")).collect(Collectors.toList());
        //编码
        List<String> numberData = entry.stream().map(i -> i.getString("nckd_examinenumber")).collect(Collectors.toList());
        unMustInputRowData.addAll(mustInputRowData);
        List<String> excelHeadList = dataHeadList.stream().flatMap(map -> map.values().stream()).filter(Objects::nonNull).filter(str -> !str.trim().isEmpty()).collect(Collectors.toList());
        if (unMustInputRowData.size() != excelHeadList.size() || !excelHeadList.containsAll(unMustInputRowData) || !dataHeadNumberList.get(0).values().containsAll(numberData)) {
            return "导入模板格式错误，请上传正确格式的数据模板!";
        }
        return "";
    }

    /**
     * 校验excel必录数据
     * @param dataHeadList 表头
     * @param dataRowList 表格
     * @return
     */
    private String checkExcelMustInputData(List<Map<Integer, String>> dataHeadList, List<Map<Integer, String>> dataRowList) {
        boolean check = false;
        //表头数据
        Map<Integer, String> integerStringMap = dataHeadList.get(0);
        //行数据
        for (Map<Integer, String> stringMap : dataRowList) {
            for (Integer i : integerStringMap.keySet()) {
                //表头
                String head = integerStringMap.get(i);
                //行数据
                String value = stringMap.get(i);
                //表头必录且行数据为空
                if (StringUtils.isBlank(value) && head.contains("*")) {
                    check = true;
                }
            }
        }
        if (check) {
            return "请填写必录项!";
        } else {
            return "";
        }
    }

    /**
     * 解析导入模板excel数据
     * @param url excel文件的url
     * @param dataHeadList 待读取表头数据
     * @param dataRowList 待读取表格数据
     * @return excel数据
     * @throws IOException
     */
    private Map<String, Object> readExcel(String url, List<Map<Integer, String>> dataHeadList, List<Map<Integer, String>> dataRowList, List<Map<Integer, String>> dataHeadNumberList) throws IOException {
        InputStream inputStream = FileServiceFactory.getAttachmentFileService().getInputStream(url);
        try {
            new ExcelReader().read(inputStream, new SheetHandler() {
                @Override
                public void handleRow(ParsedRow row) {
                    if (row.getRowNum() == 0) {
                        dataHeadNumberList.add(row.getData());
                    } else if (row.getRowNum() == 1) {
                        dataHeadList.add(row.getData());
                    } else {
                        dataRowList.add(row.getData());

                    }
                }
            });
        } catch (Exception e) {
            throw new KDBizException("读取EXCEL文件失败，请联系管理员!");
        } finally {
            inputStream.close();
        }
        return null;
    }

    private void downloadExcel() {
        // 创建工作簿（xlsx格式）
        Workbook workbook = new XSSFWorkbook();

        // 创建Sheet
        Sheet sheet = workbook.createSheet();

        // 创建样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerFont.setFontHeightInPoints((short) 12);
        headerFont.setColor(IndexedColors.RED.getIndex());
        headerStyle.setFont(headerFont);

        //导入任务id
        Long importPlanId = this.getView().getFormShowParameter().getCustomParam("importplan");
        //导入模板id
        Long templateId = this.getView().getFormShowParameter().getCustomParam("template");

        //绩效导入模板
        DynamicObject template = BusinessDataServiceHelper.loadSingle(templateId, "nckd_import_kpi_template");
        String excelName = template.getString("name");
        DynamicObjectCollection entry = template.getDynamicObjectCollection("nckd_outimptplentry");
        //绩效导入任务
//        DynamicObject importPlan = BusinessDataServiceHelper.loadSingle(importPlanId, "nckd_importplan");


        // 创建表头
        Row zeroRow = sheet.createRow(0);
        Row headerRow = sheet.createRow(1);
        for (int i = 0; i < entry.size(); i++) {
            //设置表头编码
            Cell zeroRowCell = zeroRow.createCell(i);
            String examineNumber = entry.get(i).getString("nckd_examinenumber");
            zeroRowCell.setCellValue(examineNumber);
            zeroRowCell.setCellStyle(headerStyle);

            Cell headerRowCell = headerRow.createCell(i);
            //是否必录
            boolean mustInput = entry.get(i).getBoolean("nckd_mustinput");
            //excel表头列名
            String headName = entry.get(i).getString("nckd_examinename");
            String cellValue = mustInput ? "*" + headName : headName;
            headerRowCell.setCellValue(cellValue);
            headerRowCell.setCellStyle(headerStyle);
            //设置列宽
            sheet.setColumnWidth(i, (examineNumber.length() + 5) * 256 * 2);
        }


//        //获取模板使用组织
//        DynamicObject orgObj = template.getDynamicObject("nckd_orgfield");
//        //获取下级组织id
//        List<Long> subOrgIds = OrgUnitServiceHelper.getAllSubordinateOrgs(1L, Collections.singletonList(orgObj.getLong("id")), true);
        DynamicObject[] resultUsers = BusinessDataServiceHelper.load("nckd_examinproject_result", "nckd_rank_org,nckd_remark,nckd_user,nckd_org,nckd_postbase,nckd_entryentity.nckd_result",
                new QFilter[]{new QFilter("nckd_importplan.id", QCP.equals, importPlanId).and("status", QCP.equals, "A")});
        //添加行数据
        for (int i = 0; i < resultUsers.length; i++) {
            DynamicObject resultUser = resultUsers[i];
            DynamicObject user = resultUser.getDynamicObject("nckd_user");
            DynamicObject userOrg = resultUser.getDynamicObject("nckd_org");
            DynamicObject userPost = resultUser.getDynamicObject("nckd_postbase");
            DynamicObjectCollection resultEntry = resultUser.getDynamicObjectCollection("nckd_entryentity");
            //创建行数据
            Row row = sheet.createRow(i + 2);
            //设置姓名
            Cell nameCell = row.createCell(0);
            nameCell.setCellValue(user.getString("name"));
            //设置工号
            Cell numberCell = row.createCell(1);
            numberCell.setCellValue(user.getString("number"));
            //设置行政组织
            Cell dptNameCell = row.createCell(2);
            dptNameCell.setCellValue(userOrg.getString("name"));
            //设置行政组织编码
            Cell dptNumberCell = row.createCell(3);
            dptNumberCell.setCellValue(userOrg.getString("number"));
            //设置岗位
            Cell positionNameCell = row.createCell(4);
            positionNameCell.setCellValue(userPost.getString("name"));
            //设置岗位
            Cell positionNumberCell = row.createCell(5);
            positionNumberCell.setCellValue(userPost.getString("number"));
            //设置排名单元
            Cell rank_orgCell = row.createCell(6);
            rank_orgCell.setCellValue(resultUser.getString("nckd_rank_org"));
            //设置备注
            Cell remarkCell = row.createCell(17);
            remarkCell.setCellValue(resultUser.getString("nckd_remark"));
            //设置分录数据
            if (ObjectUtils.isNotEmpty(resultEntry)) {
                for (int j = 0; j < resultEntry.size(); j++) {
                    row.createCell(j + 7).setCellValue(resultEntry.get(j).getString("nckd_result"));
                }
            }
        }

        // 保存文件
        String fileName = excelName + ".xlsx";
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            workbook.write(outputStream);
            ByteArrayInputStream inStream = new ByteArrayInputStream(outputStream.toByteArray());
            FileService fileService = FileServiceFactory.getAttachmentFileService();
            RequestContext requestContext = RequestContext.get();
            String pathParam = FileNameUtils.getAttachmentFileName(requestContext.getTenantId(), requestContext.getAccountId(), "salaryFile", fileName);
            String path = fileService.upload(new FileItem(fileName, pathParam, inStream));
            String url = UrlService.getAttachmentFullUrl(path);
            this.getView().download(url);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
