package com.yiboshi.science.utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.yiboshi.science.entity.SystemParameter;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.*;
import com.yiboshi.science.service.SystemParameterService;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.yiboshi.science.utils.ProjectInfoToPDF.getCurrentOperatingSystem;

public class TaskInfoToPDFUtil {

    static SimpleDateFormat fd = new SimpleDateFormat("yyyy-MM");
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    static SimpleDateFormat sdfM = new SimpleDateFormat("yyyy年MM月");


    /**
     * 生成项目合同书PDF
     *
     * @param dto 项目任务信息
     * @return PDF文件字节数组
     */
    public static byte[] createContractPdf(ComProjectTaskDTO dto, List<SystemParameter> list) throws DocumentException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Document document = new Document(PageSize.A4, 54f, 54f, 72f, 72f);

        try {
            // 宋体
            BaseFont sfChinese = loadChineseFont("simsun.ttc");
            // 仿宋
            BaseFont fsChinese = loadChineseFont("simfang.ttf");
            // WINGDNG2
            BaseFont WINGDNG2 = loadChineseFont("WINGDNG2.ttf");

            PdfWriter writer = PdfWriter.getInstance(document, baos);

            // 添加添加页码水印事件处理器
            writer.setPageEvent(new WatermarkPageEvent("", fsChinese));
            document.open();

            // 首页
            firstPageInfo(document, dto, sfChinese, fsChinese);

            // 填写说明
            fillInInstructions(document, sfChinese, fsChinese);

            // 项目基本信息
            baseProjectInfo(document, dto, sfChinese, fsChinese);

            // 项目组成员
            projectMemberInfo(document, dto, sfChinese, fsChinese);

            // 项目主要实施内容和目标
            projectTargetInfo(document, dto, sfChinese, fsChinese);

            // 项目经费预算表
            projectBudgetInfo(document, dto, sfChinese, fsChinese);

            // 设备费—购置设备预算明细表
            projectDeviceInfo(document, dto, sfChinese, fsChinese);

            // 设备费—试制设备预算明细表
            projectManufactureInfo(document, dto, sfChinese, fsChinese);

            // 项目承担单位研究资金支出预算明细表
            projectUnitPaymentInfo(document, dto, sfChinese, fsChinese);

            // 项目实施阶段及任务
            projectStageGoalsInfo(document, dto, sfChinese, fsChinese);

            //项目课题设置
            projectSubInfo(document, dto, sfChinese, fsChinese);

            // 添加项目绩效目标表
//          addProjectKPITable(document, dto, sfChinese, fsChinese);

            // 添加项目绩效目标表
            addProjectKPITable(document, dto, list, sfChinese, fsChinese, WINGDNG2);

            // 附件清单
            addFileTable(document, dto, sfChinese, fsChinese);

            // 共同条款
            addCommonTerms(document, dto, sfChinese, fsChinese);

            // 合同书各责任方
            addResponsibleParty(document, dto, sfChinese, fsChinese);

        } finally {
            if (document != null && document.isOpen()) {
                document.close();
            }
        }

        return baos.toByteArray();
    }

    private static void firstPageInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        Font normalFont = new Font(bfChinese, 16, Font.NORMAL);

//        // 添加附件编号
//        Paragraph attachment = new Paragraph("附件4", normalFont);
//        attachment.setAlignment(Element.ALIGN_LEFT);
//        document.add(attachment);
//        document.add(new Paragraph("\n"));

        // 从DTO获取项目编号
        Paragraph projectNoPara = new Paragraph("项目编号：" + dto.getProjNo(), normalFont);
        projectNoPara.setAlignment(Element.ALIGN_LEFT);
        document.add(projectNoPara);
        document.add(new Paragraph("\n\n\n\n\n\n"));

        // 添加标题
        Font titleFont = new Font(bfChinese, 22, Font.BOLD);
        Paragraph title = new Paragraph("省级临床医学中心科研项目合同书", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        document.add(title);
        document.add(new Paragraph("\n\n\n\n\n\n"));

        Font labelFont = new Font(bfChinese, 15, Font.NORMAL);
        // 创建表格
        PdfPTable table = new PdfPTable(5);
        table.setWidths(new float[]{70f, 15f, 15f, 50f, 210f});
        table.isLockedWidth();
        // 添加表格内容
        addTablePageCell(table, "项目名称:", null, dto.getProjName(), 4, labelFont);
        addTablePageCell(table, "项目下达单位（甲方）:", 4, "云南省卫生健康委员会", null, labelFont);
        addTablePageCell(table, "项目承担单位（乙方）:", 4, dto.getAppUnitName(), null, labelFont);
        addTablePageCell(table, "项目负责人:", 2, dto.getAppPersonName() + "     电话：" + dto.getMobile(), 3, labelFont);
        addTablePageCell(table, "项目起止年限:", 3, sdfM.format(dto.getStartDate()) + " 至 " + sdfM.format(dto.getEndDate()), 2, labelFont);
        document.add(table);
    }

    private static void fillInInstructions(Document document, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.newPage();
        Paragraph instructionTitle = new Paragraph("填写说明", new Font(bfChinese, 14, Font.BOLD));
        instructionTitle.setAlignment(Element.ALIGN_CENTER);
        document.add(instructionTitle);
        // 添加填写说明内容
        String[] instructions = {
                "一、本合同由甲、乙两方共同签订。甲方系指省卫生健康委；乙方系指省级临床医学中心依托单位。",
                "二、本合同所列内容应实事求是填写，表达要明确、严谨。对填写不符合要求的合同书，或填报内容出现虚报夸大、不切实际的，甲方将退回项目承担单位修改。",
                "三、合同书规定的项目考核指标应根据省级临床医学中心科研项目建设要求，遵循明确、量化、可考核的原则，其中技术指标应明确项目完成时达到的关键技术参数及预期可以形成的发明专利、标准、新技术、新产品、新装置、论文、专著等的数量；经济指标应明确项目完成时产生的产值、销售收入、利税、技术及产品应用所形成的市场规模、效益等。",
                "五、项目实施阶段及任务要根据省级临床医学中心科研项目建设实施内容、主要任务和目标合理安排。各阶段的任务目标是项目年度(中期检查（评估）和安排项目结转经费的依据。",
                "六、项目自筹经费指项目承担单位自行筹措，在项目执行期能够落实的非政府财政经费。原则上自筹经费以项目起始时间后项目单位自筹投入的资金进行核算。",
                "七、“科技报告类型”，包括项目验收前撰写的全面描述研究过程和技术内容的最终科技报告、项目年度或中期检查时撰写的描述本年度研究过程和进展的年度技术进展报告以及在项目实施过程中撰写的包含科研活动细节及基础数据的专题科技报告。科技报告“公开类别及时限”分为公开或延期公开，内容需要发表论文、申请专利、出版专著或涉及技术诀窍的，可标注为延期公开需要发表论文的，延期公开时限原则上在2年（含2年）以内；需要申请专利、出版专著的，延期公开时限原则上在3年（含3年）以内；涉及技术诀窍的，延期公开时限原则上在5年（含5年）以内（涉密项目科技报告按照有关规定管理）。",
                "八、省财政资金支出的预算计划应按照国家及省相关规定执行。重大、重点项目的预算计划应吸纳经费评审时提出的调整意见。",
        };
        Font contentFont = new Font(bfChinese, 14, Font.NORMAL);
        for (String instruction : instructions) {
            Paragraph para = new Paragraph(instruction, contentFont);
            para.setAlignment(Element.ALIGN_LEFT);
            para.setFirstLineIndent(28f); // 设置首行缩进
            para.setLeading(30f); // 设置行间距
            document.add(para);
        }
    }

    private static void baseProjectInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.newPage();
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加项目内容章节
        addSection(document, "一、单位基本情况", titleFont);

        // 创建表格
        PdfPTable table = new PdfPTable(8);
        table.setWidths(new float[]{80f, 80f, 30f, 60f, 60f, 80f, 30f, 100f});
        table.setWidthPercentage(100);
        // 设置表格默认边框宽度
//      table.getDefaultCell().setBorderWidth(0.1f);
        table.setSplitLate(false);          // 避免拆分时边框异
        table.isInline();

        // 添加表格内容
        addValueCell(table, "单位名称", null, dto.getAppUnitName(), 7, normalFont, null, null, null);

        addValueCell(table, "注册单位类型", null, "医疗机构", 4, normalFont, null, null, null);
        addValueCell(table, "组织机构代码/统一社会信用代码", 2, dto.getOrganizationCode(), null, normalFont, null, null, null);

        addValueCell(table, "通讯地址", null, dto.getUnitAddress(), 7, normalFont, null, null, null);

        addValueCell(table, "注册所在地", null, dto.getRegisteredAddress(), 2, normalFont, null, null, null);
        addValueCell(table, "邮编", null, dto.getPostCode(), null, normalFont, null, null, null);
        addValueCell(table, "法定代表人", null, dto.getLegalPerson(), 2, normalFont, null, null, null);

        addCell(table, "职工总数 " + dto.getWorkforce() + " （人）", 2, null, normalFont, null, null, null);
        addCell(table, "其中专科以上人员 " + dto.getSpecializedPersonnel() + " （人）", 4, null, normalFont, null, null, null);
        addCell(table, "研究开发人员 " + dto.getResearchPersonnel() + " （人）", 2, null, normalFont, null, null, null);

        addValueCell(table, "开户银行", null, dto.getDepositBank(), 4, normalFont, null, null, null);
        addValueCell(table, "银行账号", null, dto.getBankAccount(), 2, normalFont, null, null, null);

        addValueCell(table, "开户银行地址", null, dto.getDepositBankAddress(), 4, normalFont, null, null, null);
        addValueCell(table, "银行联行号", null, dto.getInterbankNumber(), 2, normalFont, null, null, null);
        document.add(table);


        // 添加项目内容章节
        addSection(document, "二、项目基本情况", titleFont);
        // 创建表格
        PdfPTable projTable = new PdfPTable(10);
        projTable.setWidths(new float[]{40f, 80f, 60f, 90f, 20f, 20f, 100f, 80f, 20f, 60f});
        projTable.setWidthPercentage(100);
        // 设置表格默认边框宽度
        projTable.getDefaultCell().setBorderWidth(0.5f);

        addValueCell(projTable, "项目编号", 2, dto.getProjNo(), 8, normalFont, null, null, null);

        addValueCell(projTable, "项目名称", 2, dto.getProjName(), 8, normalFont, null, null, null);

        addValueCell(projTable, "所属我省重点领域", 2, dto.getKeyAreas(), 8, normalFont, null, null, null);

        addValueCell(projTable, "项目开始时间", 2, fd.format(dto.getStartDate()), 2, normalFont, null, null, null);
        addValueCell(projTable, "项目结束时间", 3, fd.format(dto.getEndDate()), 3, normalFont, null, null, null);

        addValueCell(projTable, "项目负责人", 2, dto.getAppPersonName(), 2, normalFont, null, null, null);
        addValueCell(projTable, "联系电话", 3, dto.getMobile(), 3, normalFont, null, null, null);

        addValueCell(projTable, "项目联系人姓名", 2, dto.getLinkName(), 2, normalFont, null, null, null);
        addValueCell(projTable, "联系人电话", 3, dto.getLinkMobile(), 3, normalFont, null, null, null);

        addValueCell(projTable, "传真", 2, dto.getLinkFax(), 2, normalFont, null, null, null);
        addValueCell(projTable, "电子邮箱", 3, dto.getLinkEmail(), 3, normalFont, null, null, null);

        addValueCell(projTable, "项目总经费（万元）", 2, Objects.nonNull(dto.getTotalFunding()) ? dto.getTotalFunding().toString() : "", 2, normalFont, null, null, null);
        addValueCell(projTable, "财政经费（万元）", 2, Objects.nonNull(dto.getGovFunding()) ? dto.getGovFunding().toString() : "", null, normalFont, null, null, null);
        addValueCell(projTable, "自筹经费（万元）", null, Objects.nonNull(dto.getSelfFunding()) ? dto.getSelfFunding().toString() : "", 2, normalFont, null, null, null);

        addValueCell(projTable, "是否科技报告", 2, dto.getIsTechnologyReport().equals(1) ? "是" : "否", 8, normalFont, null, null, null);

        if (Objects.nonNull(dto.getIsTechnologyReport()) && dto.getIsTechnologyReport().equals(1)) {
            String commonTerms = "科技报告类型";
            Paragraph para = new Paragraph(commonTerms, normalFont);
            para.setAlignment(Element.ALIGN_LEFT);
            PdfPCell timeCell = new PdfPCell(para);
            timeCell.setMinimumHeight(25.5f);
            timeCell.setColspan(2);
            timeCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            timeCell.setHorizontalAlignment(Element.ALIGN_LEFT);
            timeCell.setCellEvent(new UniformBorderEvent());
            timeCell.setPadding(5f);
            timeCell.setBorderColor(new BaseColor(0, 0, 0));
            projTable.addCell(timeCell);

            String terms = "立项报告 份数 " + (Objects.nonNull(dto.getProjectReport()) ? dto.getProjectReport() : "0") +
                    "  进展报告 份数 " + (Objects.nonNull(dto.getProgressReport()) ? dto.getProgressReport() : "0") +
                    "  专题报告 份数 " + (Objects.nonNull(dto.getSpecialReport()) ? dto.getSpecialReport() : "0") +
                    "  最终报告 份数 " + (Objects.nonNull(dto.getFinalReport()) ? dto.getFinalReport() : "0");
            Paragraph para2 = new Paragraph(terms, normalFont);
            para.setAlignment(Element.ALIGN_LEFT);
            PdfPCell timeCell2 = new PdfPCell(para2);
            timeCell2.setMinimumHeight(25.5f);
            timeCell2.setColspan(8);
            timeCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            timeCell2.setHorizontalAlignment(Element.ALIGN_LEFT);
            timeCell2.setCellEvent(new UniformBorderEvent());
            timeCell2.setPadding(5f);
            timeCell2.setBorderColor(new BaseColor(0, 0, 0));
            projTable.addCell(timeCell2);
        }

        addCell(projTable, "项目主要参与单位及分工", 10, null, normalFont, null, null, null);

        addCell(projTable, "序号", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(projTable, "单位名称", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(projTable, "单位地址", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(projTable, "组织机构代码/统一社会信用代码", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(projTable, "分 工", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(projTable, "签字", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        for (int i = dto.getParticipateUnits() != null ? dto.getParticipateUnits().size() : 0; i < 2; i++) {
            if (dto.getParticipateUnits() == null) {
                List<ComProjectCooperativeUnitsDTO> list = new ArrayList<>();
                dto.setParticipateUnits(list);
            }
            dto.getParticipateUnits().add(new ComProjectCooperativeUnitsDTO());
        }
        for (int i = 0; i < dto.getParticipateUnits().size(); i++) {
            addCell(projTable, String.valueOf(i + 1), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(projTable, dto.getParticipateUnits().get(i).getUnitName(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(projTable, dto.getParticipateUnits().get(i).getUnitAddress(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(projTable, dto.getParticipateUnits().get(i).getOrganizationCode(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(projTable, dto.getParticipateUnits().get(i).getProjectWork(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(projTable, "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        document.add(projTable);

    }

    private static void projectMemberInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4.rotate());
        document.newPage();
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加项目内容章节
        addSection(document, "三、项目人员情况", titleFont);

        // 创建表格
        PdfPTable table = new PdfPTable(16);
        table.setWidths(new float[]{35f, 45f, 20f, 30f, 15f, 15f, 50f, 15f, 15f, 30f, 50f, 30f, 15f, 35f, 5f, 30f});
        table.setWidthPercentage(100);
        // 设置表格默认边框宽度
        table.getDefaultCell().setBorderWidth(0.5f);

        PdfPCell titleCell = new PdfPCell(new Phrase("项目负责人", new Font(bfChinese, 10.5f, Font.BOLD)));
        titleCell.setRowspan(5);
        titleCell.setColspan(2);// 合并6行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(25.5f); // 调整高度以适应内容
        table.addCell(titleCell);

        // 添加表格内容
        addValueCell(table, "姓名", 3, dto.getAppPersonName(), 3, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "性别", 2, dto.getSex(), 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "出生日期", 2, Objects.nonNull(dto.getBirthday()) ? sdf.format(dto.getBirthday()) : "", 2, normalFont, null, null, Element.ALIGN_CENTER);

        addValueCell(table, "证件类型", 3, "身份证", 3, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "证件号码", 2, dto.getCertId(), 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "民族", 2, dto.getNationName(), 2, normalFont, null, null, Element.ALIGN_CENTER);

        addValueCell(table, "职称", 3, dto.getTitleName(), 3, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "从事专业", 2, dto.getSpecName(), 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "项目分工", 2, dto.getProjWork(), 2, normalFont, null, null, Element.ALIGN_CENTER);

        addValueCell(table, "学位", 3, dto.getDegreeName(), 3, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "职务", 2, dto.getDutyName(), 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "传真", 2, dto.getFax(), 2, normalFont, null, null, Element.ALIGN_CENTER);

        addValueCell(table, "手机", 3, dto.getMobile(), 3, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "联系电话", 2, dto.getTelephone(), 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "电子邮箱", 2, dto.getEmail(), 2, normalFont, null, null, Element.ALIGN_CENTER);

        PdfPCell cell = new PdfPCell(new Phrase("项目组主要成员", new Font(bfChinese, 10.5f, Font.BOLD)));
        cell.setColspan(16);// 合并6行
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setMinimumHeight(25.5f); // 调整高度以适应内容
        table.addCell(cell);

        addCell(table, "姓名", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "出生日期", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "性别", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "职称", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "学位", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "工作单位", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "电话", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "电子邮箱", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "证件号码", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "项目分工", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "每年工作时间（月）", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "签字", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getMembers() == null || dto.getMembers().size() < 4) {
            for (int i = dto.getMembers() != null ? dto.getMembers().size() : 0; i < 4; i++) {
                if (dto.getMembers() == null) {
                    List<ComProjectMembersDTO> list = new ArrayList<>();
                    dto.setMembers(list);
                }
                dto.getMembers().add(new ComProjectMembersDTO());
            }
        }
        for (int i = 0; i < dto.getMembers().size(); i++) {
            ComProjectMembersDTO e = dto.getMembers().get(i);
            addCell(table, e.getName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, Objects.nonNull(e.getBirthday()) ? sdf.format(e.getBirthday()) : "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSex(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTitleName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getDegreeName(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getWorkUnit(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getMobile(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getEmail(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getCertId(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getProjWork(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, Objects.nonNull(e.getForMonths()) ? e.getForMonths().toString() : "", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }

        addValueCell(table, "项目组人数", 2, Objects.nonNull(dto.getMemCount()) ? dto.getMemCount().toString() + "人" : "0" + "人", null, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "高级", null, Objects.nonNull(dto.getMemHighCount()) ? dto.getMemHighCount().toString() + "人" : "0" + "人", 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "中级", null, Objects.nonNull(dto.getMemMiddleCount()) ? dto.getMemMiddleCount().toString() + "人" : "0" + "人", 2, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "初级", null, Objects.nonNull(dto.getMemLowCount()) ? dto.getMemLowCount().toString() + "人" : "0" + "人", null, normalFont, null, null, Element.ALIGN_CENTER);
        addValueCell(table, "其他", 2, "0 人", 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "--", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        document.add(table);
    }

    private static void projectTargetInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4);
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 14f, Font.NORMAL);

        // 添加项目内容章节
        addSection(document, "四、项目主要实施内容和目标", titleFont);

        // 创建表格
        PdfPTable table = new PdfPTable(1);
        table.setWidths(new float[]{100f});
        table.setWidthPercentage(100);
        // 设置表格默认边框宽度
        table.getDefaultCell().setBorderWidth(0.5f);

        addCell(table, "项目实施目标", null, null, titleFont, null, null, null);
        addTableContentCell(table, "", dto.getResearchContent(), null, normalFont, 200f);

        addCell(table, "项目考核指标", null, null, titleFont, null, null, null);
        addTableContentCell(table, "1、主要技术指标：", dto.getTechnologyTarget(), null, normalFont, 200f);

        addTableContentCell(table, "2、主要经济指标：", dto.getEconomyTarget(), null, normalFont, 200f);

        addTableContentCell(table, "3、项目实施中形成的示范基地、中试线、生产线及其规模等：", dto.getAchievementTarget(), null, normalFont, 200f);

        addTableContentCell(table, "4、科技报告考核指标", dto.getTechnologyReportsTarget(), null, normalFont, 200f);

        addTableContentCell(table, "5、其他应考核的指标：", dto.getOtherTarget(), null, normalFont, 200f);

        document.add(table);
    }

    private static void projectBudgetInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4);
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 14f, Font.NORMAL);

        // 添加项目内容章节
        addSection(document, "五、项目经费预算表", titleFont);

        Paragraph section = new Paragraph("金额单位：万元（保留两位小数）", new Font(bfChinese, 10.5f, Font.NORMAL));
        section.setSpacingBefore(15);
        section.setSpacingAfter(10);
        section.setAlignment(Element.ALIGN_RIGHT);
        document.add(section);

        // 创建表格
        PdfPTable table = new PdfPTable(8);
        table.setWidths(new float[]{160f, 80f, 20f, 80f, 20f, 80f, 20f, 80f});
        table.setWidthPercentage(100);
        // 设置表格默认边框宽度
        table.getDefaultCell().setBorderWidth(0.5f);

        addCell(table, "预算科目", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "总预算数", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "财政资金", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "自筹资金", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "备注", 2, null, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getBudget() == null || dto.getBudget().size() < 23) {
            for (int i = dto.getBudget() != null ? dto.getBudget().size() : 0; i < 23; i++) {
                if (dto.getBudget() == null) {
                    List<ComProjectBudgetDTO> list = new ArrayList<>();
                    dto.setBudget(list);
                }
                dto.getBudget().add(new ComProjectBudgetDTO());
            }
        }
        for (int i = 0; i < dto.getBudget().size(); i++) {
            ComProjectBudgetDTO e = dto.getBudget().get(i);
            addCell(table, e.getBudgetName(), null, null, normalFont, null, null, null);
            addCell(table, e.getTotalBudget(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getApplyFunds(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSelfFunds(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalBudget(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        }

        addCell(table, "三、分年度用款计划", 8, null, titleFont, null, null, null);

        addCell(table, "年度", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "第一年", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "第二年", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "第三年", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "合计", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getFundPlan() == null || dto.getFundPlan().size() < 3) {
            for (int i = dto.getFundPlan() != null ? dto.getFundPlan().size() : 0; i < 3; i++) {
                if (dto.getFundPlan() == null) {
                    List<ComProjectFundPlanDTO> list = new ArrayList<>();
                    dto.setFundPlan(list);
                }
                dto.getFundPlan().add(new ComProjectFundPlanDTO());
            }
        }
        for (int i = 0; i < dto.getFundPlan().size(); i++) {
            ComProjectFundPlanDTO e = dto.getFundPlan().get(i);
            addCell(table, e.getFundName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getYearValue1(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getYearValue2(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getYearValue3(), 2, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        document.add(table);
    }

    private static void projectDeviceInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4.rotate());
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加标题
        addSection(document, "设备费—购置设备预算明细表", titleFont);

        // 添加单位说明
        Paragraph unitDesc = new Paragraph("单位：万元（保留两位小数）", normalFont);
        unitDesc.setAlignment(Element.ALIGN_RIGHT);
        unitDesc.setSpacingAfter(10f);
        document.add(unitDesc);

        // 创建表格
        PdfPTable table = new PdfPTable(15);
        float[] columnWidths = {25f, 60f, 50f, 40f, 30f, 40f, 40f, 40f, 40f, 40f, 40f, 40f, 40f, 60f, 60f};
        table.setWidths(columnWidths);
        table.setWidthPercentage(100);

        addCell(table, "序号", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "设备名称", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "功能和技术指标", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "单价（万元/台套）", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "数量（台套）", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "金额", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "资金来源", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "购置单位", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "存放单位（地点）", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "购置设备类型", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "主要生产厂家及国别", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "规格型号", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "拟开放共享范围", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "购置必要性及对项目研究的作用和用途", null, 2, normalFont, null, null, Element.ALIGN_CENTER);

        addCell(table, "财政\n" + "资金", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "自筹\n" + "资金", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getDeviceList() == null || dto.getDeviceList().size() < 2) {
            for (int i = dto.getDeviceList() != null ? dto.getDeviceList().size() : 0; i < 2; i++) {
                if (dto.getDeviceList() == null) {
                    List<ComProjectEquipmentDTO> list = new ArrayList<>();
                    dto.setDeviceList(list);
                }
                dto.getDeviceList().add(new ComProjectEquipmentDTO());
            }
        }

        int fiftyUpNumber = 0;
        int fiftyDownNumber = 0;
        int totalNumber = 0;

        BigDecimal fiftyUpAmount = new BigDecimal(0.0);
        BigDecimal fiftyDownAmount = new BigDecimal(0);
        BigDecimal totalAmount = new BigDecimal(0);

        for (int i = 0; i < dto.getDeviceList().size(); i++) {
            ComProjectEquipmentDTO e = dto.getDeviceList().get(i);
            if (Objects.nonNull(e.getQuantity()) && Objects.nonNull(e.getUnitPrice())) {
                int result = e.getUnitPrice().compareTo(new BigDecimal(5));
                if (result >= 0) {
                    fiftyUpNumber += e.getQuantity();
                    fiftyUpAmount = fiftyUpAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
                } else {
                    fiftyDownNumber += e.getQuantity();
                    fiftyDownAmount = fiftyDownAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
                }
                totalNumber += e.getQuantity();
                totalAmount = totalAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
            }

            addCell(table, i + 1, null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getFunctionTarget(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getUnitPrice(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getQuantity(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalBudget(), null, null, normalFont, null, null, Element.ALIGN_CENTER);

            addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);

            addCell(table, e.getBuyUnit(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getStorageLocation(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getEquipmentType(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getManufacturer(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSpecificationType(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSharedScope(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getUseFrom(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        addCell(table, "单价5万元以上购置设备合计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);

        addCell(table, "单价5万元以下购置设备合计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);

        addCell(table, "累  计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, '/', null, null, normalFont, null, null, Element.ALIGN_CENTER);

        document.add(table);
    }

    private static void projectManufactureInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4.rotate());
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加标题
        addSection(document, "设备费—试制设备预算明细表", titleFont);

        // 添加单位说明
        Paragraph unitDesc = new Paragraph("单位：万元（保留两位小数）", normalFont);
        unitDesc.setAlignment(Element.ALIGN_RIGHT);
        unitDesc.setSpacingAfter(10f);
        document.add(unitDesc);

        // 创建表格
        PdfPTable table = new PdfPTable(10);
        float[] columnWidths = {25f, 60f, 60f, 40f, 25f, 40f, 40f, 40f, 40f, 40f};
        table.setWidths(columnWidths);
        table.setWidthPercentage(100);

        addCell(table, "序号", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "设备名称", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "功能和技术指标", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "单价（万元/台套）", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "数量（台套）", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "金额", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "资金来源", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "试制单位", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "安置单位", null, 2, normalFont, null, null, Element.ALIGN_CENTER);

        addCell(table, "财政\n" + "资金", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "自筹\n" + "资金", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getManufactureList() == null || dto.getManufactureList().size() < 2) {
            for (int i = dto.getManufactureList() != null ? dto.getManufactureList().size() : 0; i < 2; i++) {
                if (dto.getManufactureList() == null) {
                    List<ComProjectManufactureDTO> list = new ArrayList<>();
                    dto.setManufactureList(list);
                }
                dto.getManufactureList().add(new ComProjectManufactureDTO());
            }
        }

        int fiftyUpNumber = 0;
        BigDecimal fiftyUpAmount = new BigDecimal(0.0);
        BigDecimal fiftyUpGovFun = new BigDecimal(0.0);
        BigDecimal fiftyUpSelfFun = new BigDecimal(0.0);

        int fiftyDownNumber = 0;
        BigDecimal fiftyDownAmount = new BigDecimal(0.0);
        BigDecimal fiftyDownGovFun = new BigDecimal(0.0);
        BigDecimal fiftyDownSelfFun = new BigDecimal(0.0);

        int totalNumber = 0;
        BigDecimal totalAmount = new BigDecimal(0.0);
        BigDecimal totalGovFun = new BigDecimal(0.0);
        BigDecimal totalSelfFun = new BigDecimal(0.0);

        for (int i = 0; i < dto.getManufactureList().size(); i++) {
            ComProjectManufactureDTO e = dto.getManufactureList().get(i);
            if (Objects.nonNull(e.getUnitPrice())) {
                int result = e.getUnitPrice().compareTo(new BigDecimal(5));
                if (result >= 0) {
                    if (Objects.nonNull(e.getQuantity())) {
                        fiftyUpNumber += e.getQuantity();
                        fiftyUpAmount = fiftyUpAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
                    }
                    if (Objects.nonNull(e.getFundAmount())) {
                        fiftyUpGovFun = fiftyUpGovFun.add(e.getFundAmount());
                    }
                    if (Objects.nonNull(e.getSelfAmount())) {
                        fiftyUpSelfFun = fiftyUpSelfFun.add(e.getSelfAmount());
                    }
                } else {
                    if (Objects.nonNull(e.getQuantity())) {
                        fiftyDownNumber += e.getQuantity();
                        fiftyDownAmount = fiftyDownAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
                    }
                    if (Objects.nonNull(e.getFundAmount())) {
                        fiftyDownGovFun = fiftyDownGovFun.add(e.getFundAmount());
                    }
                    if (Objects.nonNull(e.getSelfAmount())) {
                        fiftyDownSelfFun = fiftyDownSelfFun.add(e.getSelfAmount());
                    }
                }
                if (Objects.nonNull(e.getQuantity())) {
                    totalNumber += e.getQuantity();
                    totalAmount = totalAmount.add(e.getUnitPrice().multiply(new BigDecimal(e.getQuantity())));
                }
                if (Objects.nonNull(e.getFundAmount())) {
                    totalGovFun = totalGovFun.add(e.getFundAmount());
                }
                if (Objects.nonNull(e.getSelfAmount())) {
                    totalSelfFun = totalSelfFun.add(e.getSelfAmount());
                }
            }
            addCell(table, i + 1, null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getFunctionTarget(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getUnitPrice(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getQuantity(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalBudget(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getFundAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSelfAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getManufactureUnit(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getStorageUnit(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        addCell(table, "单价5万元以上购置设备合计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpGovFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyUpSelfFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        addCell(table, "单价5万元以下购置设备合计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownGovFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, fiftyDownSelfFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);


        addCell(table, "累  计", 3, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalNumber, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalGovFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalSelfFun, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "/", null, null, normalFont, null, null, Element.ALIGN_CENTER);

        document.add(table);
    }

    private static void projectUnitPaymentInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        // 添加横向页面
        document.setPageSize(PageSize.A4.rotate());
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加标题
        addSection(document, "项目承担单位研究资金支出预算明细表", titleFont);

        // 添加单位说明
        Paragraph unitDesc = new Paragraph("金额单位：万元", normalFont);
        unitDesc.setAlignment(Element.ALIGN_RIGHT);
        unitDesc.setSpacingAfter(10f);
        document.add(unitDesc);

        // 创建表格
        PdfPTable table = new PdfPTable(10);
        float[] columnWidths = {25f, 60f, 60f, 40f, 25f, 40f, 40f, 40f, 40f, 60f};
        table.setWidths(columnWidths);
        table.setWidthPercentage(100);

        addCell(table, "序号", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "单位名称", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "统一社会信用代码", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "单位类型", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "任务分工", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "研究任务负责人", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "合计", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "省级财政资金", 2, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "其他来源资金", null, 2, normalFont, null, null, Element.ALIGN_CENTER);


        addCell(table, "小计", null, null, normalFont, null, null, null);
        addCell(table, "其中：间接\n" + "费用", null, null, normalFont, null, null, null);

        if (dto.getUnitPayment() == null || dto.getUnitPayment().size() < 2) {
            for (int i = dto.getUnitPayment() != null ? dto.getUnitPayment().size() : 0; i < 2; i++) {
                if (dto.getUnitPayment() == null) {
                    List<ComProjectUnitPaymentDTO> list = new ArrayList<>();
                    dto.setUnitPayment(list);
                }
                dto.getUnitPayment().add(new ComProjectUnitPaymentDTO());
            }
        }

        BigDecimal totalAmount = new BigDecimal(0.0);
        BigDecimal totalFundAmount = new BigDecimal(0.0);
        BigDecimal totalIndirectFee = new BigDecimal(0.0);
        BigDecimal totalSelfAmount = new BigDecimal(0.0);

        for (int i = 0; i < dto.getUnitPayment().size(); i++) {
            ComProjectUnitPaymentDTO e = dto.getUnitPayment().get(i);
            if (Objects.nonNull(e.getTotalAmount())) {
                totalAmount = totalAmount.add(e.getTotalAmount());
            }
            if (Objects.nonNull(e.getFundAmount())) {
                totalFundAmount = totalFundAmount.add(e.getFundAmount());
            }
            if (Objects.nonNull(e.getIndirectFee())) {
                totalIndirectFee = totalIndirectFee.add(e.getIndirectFee());
            }
            if (Objects.nonNull(e.getSelfAmount())) {
                totalSelfAmount = totalSelfAmount.add(e.getSelfAmount());
            }
            addCell(table, i + 1, null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getUnitName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSocialCode(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getRoleName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTaskDivision(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTaskLeader(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getFundAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getIndirectFee(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSelfAmount(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        addCell(table, "累  计", 6, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalFundAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalIndirectFee, null, null, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, totalSelfAmount, null, null, normalFont, null, null, Element.ALIGN_CENTER);

        document.add(table);

//        Paragraph para = new Paragraph("\n", normalFont);
//        para.setAlignment(Element.ALIGN_LEFT);
//        document.add(para);
        Paragraph para1 = new Paragraph("注：1.单位类型为项目承担单位、项目参加单位；", normalFont);
        para1.setAlignment(Element.ALIGN_LEFT);
        para1.setFirstLineIndent(28f); // 设置首行缩进
        document.add(para1);
        Paragraph para2 = new Paragraph("2.任务分工的描述应该简洁，不超过300字。", normalFont);
        para2.setAlignment(Element.ALIGN_LEFT);
        para2.setFirstLineIndent(49f); // 设置首行缩进
        document.add(para2);
    }

    private static void projectStageGoalsInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.setPageSize(PageSize.A4);
        document.newPage();

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加标题
        addSection(document, "六、项目实施阶段及任务", titleFont);
        // 创建表格
        PdfPTable table = new PdfPTable(3);
        table.setWidths(new float[]{30f, 150f, 320f});
        table.setWidthPercentage(100);

        // 添加表头
        addCell(table, "序号", null, null, normalFont, 30f, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        addCell(table, "时间", null, null, normalFont, 30f, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        addCell(table, "计划完成内容和关键节点目标", null, null, normalFont, 30f, Element.ALIGN_CENTER, Element.ALIGN_CENTER);

        if (dto.getStageGoals() == null || dto.getStageGoals().size() < 3) {
            for (int i = dto.getStageGoals() != null ? dto.getStageGoals().size() : 0; i < 3; i++) {
                if (dto.getStageGoals() == null) {
                    List<ComProjectStageGoalDTO> list = new ArrayList<>();
                    dto.setStageGoals(list);
                }
                dto.getStageGoals().add(new ComProjectStageGoalDTO());
            }
        }
        for (int i = 0; i < dto.getStageGoals().size(); i++) {
            ComProjectStageGoalDTO e = dto.getStageGoals().get(i);
            addCell(table, String.valueOf(i + 1), null, null, normalFont, 120f, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
            Paragraph timePara = new Paragraph();
            timePara.add(new Chunk("第" + numberTo(i + 1) + "阶段\n", normalFont));
            if (Objects.nonNull(e.getStartTime()) && Objects.nonNull(e.getEndTime()))
                timePara.add(new Chunk(sdfM.format(e.getStartTime()) + " 至 " + sdfM.format(e.getEndTime()), normalFont));
            else
                timePara.add(new Chunk("__年__月 至 __年__月", normalFont));
            timePara.setAlignment(Element.ALIGN_CENTER);

            PdfPCell timeCell = new PdfPCell(timePara);
            timeCell.setCellEvent(new UniformBorderEvent());
            timeCell.setMinimumHeight(120f);
            timeCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            timeCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            timeCell.setBorderColor(new BaseColor(0, 0, 0));
            table.addCell(timeCell);

            addCell(table, e.getTarget(), null, null, normalFont, 120f, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        }
        document.add(table);
    }

    private static void projectSubInfo(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {

        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);

        // 添加标题
        addSection(document, "七、项目课题设置", titleFont);

        // 创建表格
        PdfPTable table = new PdfPTable(7);
        float[] columnWidths = {25f, 60f, 60f, 40f, 25f, 40f, 40f};
        table.setWidths(columnWidths);
        table.setWidthPercentage(100);

        addCell(table, "序号", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "课题名称", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "承担单位", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "课题负责人", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "课题预算总经费", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "其中：省科技经费", null, 2, normalFont, null, null, Element.ALIGN_CENTER);
        addCell(table, "自筹经费", null, 2, normalFont, null, null, Element.ALIGN_CENTER);

        if (dto.getProjectSubList() == null || dto.getProjectSubList().size() < 3) {
            for (int i = dto.getProjectSubList() != null ? dto.getProjectSubList().size() : 0; i < 3; i++) {
                if (dto.getProjectSubList() == null) {
                    List<ComProjectSubDTO> list = new ArrayList<>();
                    dto.setProjectSubList(list);
                }
                dto.getProjectSubList().add(new ComProjectSubDTO());
            }
        }
        for (int i = 0; i < dto.getProjectSubList().size(); i++) {
            ComProjectSubDTO e = dto.getProjectSubList().get(i);
            addCell(table, i + 1, null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getProjName(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getUndertakingUnit(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getDirector(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getTotalBudget() != null ? e.getTotalBudget().setScale(2, RoundingMode.HALF_UP).toString() : "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getGovBudget() != null ? e.getGovBudget().setScale(2, RoundingMode.HALF_UP).toString() : "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(table, e.getSelfBudget() != null ? e.getSelfBudget().setScale(2, RoundingMode.HALF_UP).toString() : "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        document.add(table);
    }


    private static void addProjectKPITable(Document document, ComProjectTaskDTO task, List<SystemParameter> projAttributeList, BaseFont bfChinese, BaseFont fsChinese, BaseFont WINGDNG2) throws DocumentException {
        document.setPageSize(PageSize.A4.rotate());
        document.newPage();
        Font titleFont = new Font(bfChinese, 12, Font.NORMAL);
        Font contentFont = new Font(bfChinese, 12, Font.NORMAL);
        Font wingdng2Font = new Font(WINGDNG2, 12, Font.NORMAL);
        ProjectKPIStatisticDTO kpitDTO = task.getProjectKPI();
        List<ComProjectKpitDTO> detail = task.getProjectKPI().getThreeLevel();

        // 添加标题
        addSection(document, "八、绩效目标表", titleFont);

        // 创建主表格
        PdfPTable mainTable = new PdfPTable(5);
        mainTable.setWidthPercentage(98);
        float[] widths = {0.8f, 1f, 2f, 1f, 2f};
        mainTable.setWidths(widths);

        // 添加年度标题
        PdfPCell yearCell = new PdfPCell(new Phrase(kpitDTO.getReportYear() + "年度", titleFont));
        yearCell.setColspan(5);
        yearCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        yearCell.setMinimumHeight(25f);
        mainTable.addCell(yearCell);

        // 项目名称和实施单位
        addLabelValueRow(mainTable, "项目名称", kpitDTO.getProjName(), 2, titleFont, contentFont);
        addLabelValueRow(mainTable, "实施单位", kpitDTO.getAppUnitName(), 1, titleFont, contentFont);

        // 项目属性
        PdfPCell labelCell = new PdfPCell(new Phrase("项目属性", titleFont));
        labelCell.setMinimumHeight(25f);
        labelCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        mainTable.addCell(labelCell);

        // 创建复选框和文字组合
        Phrase checkboxPhrase = new Phrase();
        if (Objects.nonNull(kpitDTO.getProjAttribute())) {
            for (SystemParameter param : projAttributeList) {
                if (param.getId().toLowerCase().equals(kpitDTO.getProjAttribute().toLowerCase())) {
                    checkboxPhrase.add(new Chunk("R", wingdng2Font));  // 选中状态
                } else {
                    checkboxPhrase.add(new Chunk("£", wingdng2Font));  // 未选中状态
                }
                checkboxPhrase.add(new Chunk(" " + param.getName() + "    ", contentFont));  // 使用中文字体显示文字
            }
        } else {
            checkboxPhrase.add(new Chunk("£", wingdng2Font));
            checkboxPhrase.add(new Chunk(" 新增项目    ", contentFont));
            checkboxPhrase.add(new Chunk("£", wingdng2Font));
            checkboxPhrase.add(new Chunk(" 延续项目", contentFont));
        }

        PdfPCell valueCell = new PdfPCell(checkboxPhrase);
        valueCell.setMinimumHeight(25f);
        valueCell.setColspan(2);
        mainTable.addCell(valueCell);

        // 项目期
        addLabelValueRow(mainTable, "项目期", kpitDTO.getProjDeadline(), 1, titleFont, contentFont);

        // 项目资金（万元）标题行
        PdfPCell fundTitle = new PdfPCell(new Phrase("项目资金\n（万元）", titleFont));
        fundTitle.setRowspan(3);
        fundTitle.setVerticalAlignment(Element.ALIGN_MIDDLE);
        fundTitle.setHorizontalAlignment(Element.ALIGN_CENTER);
        mainTable.addCell(fundTitle);

        // 总体资金总额和年度资金总额
        addLabelValueRow(mainTable, "总体资金总额", kpitDTO.getTotalBudget().toString(), 1, titleFont, contentFont);
        addLabelValueRow(mainTable, "年度资金总额", kpitDTO.getYearTotal().toString(), 1, titleFont, contentFont);

        // 其中：财政拨款（两行）
        addLabelValueRow(mainTable, "其中：财政拨款", kpitDTO.getApplyFunds().toString(), 1, titleFont, contentFont);
        addLabelValueRow(mainTable, "其中：财政拨款", kpitDTO.getYearApply().toString(), 1, titleFont, contentFont);

        // 其他资金（两行）
        addLabelValueRow(mainTable, "其他资金", kpitDTO.getSelfFunds().toString(), 1, titleFont, contentFont);
        addLabelValueRow(mainTable, "其他资金", kpitDTO.getYearSelf().toString(), 1, titleFont, contentFont);

        document.add(mainTable);

        // 总体考核目标
        PdfPTable middleTable = new PdfPTable(5);
        middleTable.setWidthPercentage(98);
        float[] middleWidths = {0.8f, 3.2f, 1f, 1f, 1f};
        middleTable.setWidths(middleWidths);

        // 添加左侧标题单元格
        PdfPCell titleCell = new PdfPCell(new Phrase("总体考核\n目标", titleFont));
        titleCell.setRowspan(3);  // 合并三行
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        middleTable.addCell(titleCell);

        // 添加总体目标标题行
        int startYear = DateUtils.getDateYear(kpitDTO.getStartDate());
        int endYear = DateUtils.getDateYear(kpitDTO.getEndDate());
        PdfPCell totalTargetCell = new PdfPCell(new Phrase("总体目标（" + startYear + "年—" + endYear + "年）", titleFont));
        totalTargetCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        totalTargetCell.setMinimumHeight(25f);
        middleTable.addCell(totalTargetCell);

        // 添加分年度指标标题行
        PdfPCell yearlyTitleCell = new PdfPCell(new Phrase("分年度指标", titleFont));
        yearlyTitleCell.setColspan(3); // 合并三列
        yearlyTitleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        yearlyTitleCell.setMinimumHeight(25f);
        middleTable.addCell(yearlyTitleCell);

        // 添加总体目标内容
        PdfPCell totalTargetContentCell = new PdfPCell(new Phrase(kpitDTO.getYearTarget(), contentFont));
        totalTargetContentCell.setRowspan(2); // 合并两行
        totalTargetContentCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        totalTargetContentCell.setMinimumHeight(50f);  // 设置较大的高度以容纳多行内容
        middleTable.addCell(totalTargetContentCell);

        // 添加年度标题行
        for (int i = 0; i < 3; i++) {
            PdfPCell yearCCell = new PdfPCell(new Phrase((startYear + i) + "年", titleFont));
            yearCCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            yearCCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            yearCCell.setMinimumHeight(25f);
            middleTable.addCell(yearCCell);
        }

        // 添加年度内容
        PdfPCell yearContentCell = new PdfPCell(new Phrase(kpitDTO.getYear1Goal(), contentFont));
        yearContentCell.setMinimumHeight(50f);
        yearContentCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        middleTable.addCell(yearContentCell);
        yearContentCell = new PdfPCell(new Phrase(kpitDTO.getYear2Goal(), contentFont));
        yearContentCell.setMinimumHeight(50f);
        yearContentCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        middleTable.addCell(yearContentCell);
        yearContentCell = new PdfPCell(new Phrase(kpitDTO.getYear3Goal(), contentFont));
        yearContentCell.setMinimumHeight(50f);
        yearContentCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        middleTable.addCell(yearContentCell);

        document.add(middleTable);

        addTargetDetailTable(document, kpitDTO, titleFont, contentFont);

    }

    private static void addTargetDetailTable(Document document, ProjectKPIStatisticDTO kpitDTO, Font titleFont, Font contentFont) throws DocumentException {
        PdfPTable detailTable = new PdfPTable(11);
        detailTable.setWidthPercentage(98);
        float[] detailWidths = {0.5f, 0.5f, 0.5f, 1.5f, 0.5f, 0.5f, 0.5f, 1.5f, 0.5f, 0.5f, 0.5f};
        detailTable.setWidths(detailWidths);

        //总考核目标
        addTitleCell(detailTable, "总体考核目标", 0, kpitDTO.getTotalRowSpan(), titleFont);
        //一级指标
        addTitleCell(detailTable, "一级指标", 0, 2, titleFont);
        //二级指标
        addTitleCell(detailTable, "二级指标", 0, 2, titleFont);
        //三级指标
        addTitleCell(detailTable, "三级指标", 0, 2, titleFont);
        //指标值
        addTitleCell(detailTable, "指标值", 0, 2, titleFont);
        //绩效标准
        addTitleCell(detailTable, "绩效标准", 0, 2, titleFont);
        //二级指标
        addTitleCell(detailTable, "二级指标", 0, 2, titleFont);
        //三级指标
        addTitleCell(detailTable, "三级指标", 0, 2, titleFont);
        //指标值
        addTitleCell(detailTable, "指标值", 3, 0, titleFont);

        int startYear = DateUtils.getDateYear(kpitDTO.getStartDate());
        addTitleCell(detailTable, startYear + "年", 0, 0, contentFont);
        addTitleCell(detailTable, (startYear + 1) + "年", 0, 0, contentFont);
        addTitleCell(detailTable, (startYear + 2) + "年", 0, 0, contentFont);

        List<ComProjectKpitDTO> list = kpitDTO.getThreeLevel();
        for (int i = 0; i < list.size(); i++) {
            ComProjectKpitDTO model = list.get(i);
            if (model.getOneDisplay())
                addTitleCell(detailTable, model.getOneLevelName(), 0, model.getOneRowSpan(), contentFont);

            if (model.getTowDisplay())
                addTitleCell(detailTable, model.getTowLevelName(), 0, model.getTowRowSpan(), contentFont);

            addTitleCell(detailTable, model.getKpitName(), 0, 0, contentFont);
            addTitleCell(detailTable, model.getTargetValue() != null ? model.getTargetValue().toString() : "", 0, 0, contentFont);
            addTitleCell(detailTable, model.getPerformanceStandard() != null ? model.getPerformanceStandard().toString() : "", 0, 0, contentFont);

            if (model.getTowDisplay())
                addTitleCell(detailTable, model.getTowLevelName(), 0, model.getTowRowSpan(), contentFont);

            addTitleCell(detailTable, model.getKpitName(), 0, 0, contentFont);

            addTitleCell(detailTable, model.getYearValue1() != null ? model.getYearValue1().toString() : "", 0, 0, contentFont);
            addTitleCell(detailTable, model.getYearValue2() != null ? model.getYearValue2().toString() : "", 0, 0, contentFont);
            addTitleCell(detailTable, model.getYearValue3() != null ? model.getYearValue3().toString() : "", 0, 0, contentFont);
        }

        document.add(detailTable);
    }

    private static void addTitleCell(PdfPTable detailTable, String title, int colSpan, int rowSpan, Font contentFont) {
        PdfPCell titleCell = new PdfPCell(new Phrase(title, contentFont));
        if (colSpan > 1)
            titleCell.setColspan(colSpan);
        if (rowSpan > 1)
            titleCell.setRowspan(rowSpan);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        detailTable.addCell(titleCell);
    }

    private static void addFileTable(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.setPageSize(PageSize.A4);
        document.newPage();
        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 12f, Font.NORMAL);
        Font labelFont = new Font(bfChinese, 11f, Font.NORMAL);

        // 添加标题
        addSection(document, "九、附件清单", titleFont);

        // 创建附件清单表格
        PdfPTable fileTable = new PdfPTable(4);
        fileTable.setWidths(new float[]{80f, 300f, 80f, 200f});
        fileTable.setWidthPercentage(100);

        // 表头
        addCell(fileTable, "序号", null, null, labelFont, null, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        addCell(fileTable, "附件名称", null, null, labelFont, null, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        addCell(fileTable, "份数", null, null, labelFont, null, Element.ALIGN_CENTER, Element.ALIGN_CENTER);
        addCell(fileTable, "备注", null, null, labelFont, null, Element.ALIGN_CENTER, Element.ALIGN_CENTER);

        if (dto.getFileList() == null || dto.getFileList().size() < 1) {
            for (int i = dto.getFileList() != null ? dto.getFileList().size() : 0; i < 1; i++) {
                if (dto.getFileList() == null) {
                    List<ComFileDTO> list = new ArrayList<>();
                    dto.setFileList(list);
                }
                dto.getFileList().add(new ComFileDTO());
            }
        }
        for (int i = 0; i < dto.getFileList().size(); i++) {
            ComFileDTO e = dto.getFileList().get(i);
            addCell(fileTable, i + 1, null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(fileTable, e.getFileExplain(), null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(fileTable, Objects.nonNull(e.getFileName()) ? "1" : "0", null, null, normalFont, null, null, Element.ALIGN_CENTER);
            addCell(fileTable, "", null, null, normalFont, null, null, Element.ALIGN_CENTER);
        }
        document.add(fileTable);
    }

    private static void addCommonTerms(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.newPage();
        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 10.5f, Font.NORMAL);
//      Font contentFont = new Font(bfChinese, 12f, Font.NORMAL);
        Font contentFont = new Font(bfChinese, 14, Font.NORMAL);

        // 添加标题
        addSection(document, "十、共同条款", titleFont);

        Paragraph instructionTitle = new Paragraph("合同书各责任方", new Font(bfChinese, 14, Font.BOLD));
        instructionTitle.setAlignment(Element.ALIGN_CENTER);
        document.add(instructionTitle);
        // 共同条款内容
        String[] commonTerms = {
                "第一条 合同签约各方根据《中华人民共和国合同法》及国家有关法规和规定，经协商一致，特订立本合同，作为甲乙两方在项目实施管理过程中共同遵守的依据。",
                "第二条 甲方的权利义务：1.按合同书规定进行经费核拨及有关工作协调。2.按照合同约定，对乙方项目的实施情况和经费到位、使用情况进行监督、检查。",
                "第三条 乙方的权利义务：1.落实自筹经费，为项目实施提供技术与条件保障。2.规范财务管理，按合同书规定，对甲方核拨的经费做到专款专用，设置会计明细帐单独核算，并结合预算据实核算。3.甲方对乙方项目实施情况及经费使用情况进行中期评估、绩效评价和巡视检查。4.按要求于项目实施期内按年度向甲方报送项目及预算执行情况报告。5.按规定提出验收或终止项目的申请，并按甲方要求做好项目验收工作。",
                "第四条 在履行本合同的过程中，如出现相关政策法规重大改变等不可抗力情况，甲方有权对所核拨经费的数量和时间进行相应调整。对分期拨款项目，根据项目研究进展或中期评估、乙方信用、审计及经营等情况，甲方有权减拨或停拨后续经费。因非不可抗力因素导致的项目未履行或未履行完毕，或因乙方责任造成项目终止的，甲方有权终止项目合同，收回尚未使用和使用不符合规定的财政经费，乙方拒不退回经费的，甲方通过司法途径收回财政经费。",
                "第五条 在履行本合同的过程中，当事人一方发现可能导致项目整体或部分失败的情形时，应及时通知另一方，并采取适当措施减少损失，没有及时通知并采取适当措施，致使损失扩大的，应当就扩大的损失承担责任。",
                "第六条 在履行本合同过程中，合同内容各方不得擅自变更和修改。",
                "第七条 实施项目所获得的科技成果（知识产权）归属、成果转让和实施技术成果所产生的经济利益的分享，除双方另有约定外，按照国家和云南省有关规定执行。项目如涉及多家（包含两家）单位参加，乙方应在签订本合同前与有关单位就合作任务和知识产权分配等问题签订有关合同或协议，作为本合同的附件。",
                "第八条 乙方应守法诚信开展相关科研活动，如发生严重不良科研诚信行为，甲方将参照《云南省科技厅科技计划项目管理办法》及《云南省科技计划项目资金管理办法》有关规定处理。甲方有权就乙方及项目负责人的科研诚信信息，按照有关规定向其他行政管理部门或社会公布。",
                "第九条 属技术保密的项目，甲乙双方应另行订立技术保密条款，作为本合同正式内容的一部分，与本合同具有同等效力。",
                "第十条 有关合同的未尽事宜，按照国家、省有关科技计划与经费管理的规定执行。",
                "第十一条 本合同若发生争议，双方应协商解决，协商不成的，由甲方所在地法院进行管辖。",
                "第十二条 本合同经甲乙双方签字盖章后生效，甲方执两份，乙方执一份，均具有同等法律效力。",
                "第十三条 有关各方补充条款（作为本合同正式内容的一部分，与本合同具有同等效力）。"
        };

        for (String term : commonTerms) {
            Paragraph para = new Paragraph(term, contentFont);
            para.setAlignment(Element.ALIGN_LEFT);
            para.setFirstLineIndent(28f); // 设置首行缩进
//            para.setLeading(24f); // 设置行间距
            document.add(para);
//          document.add(new Paragraph("\n")); // 添加段落间距
        }
    }

    private static void addResponsibleParty(Document document, ComProjectTaskDTO dto, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        document.newPage();
        Font titleFont = new Font(bfChinese, 14f, Font.BOLD);
        Font normalFont = new Font(bfChinese, 12f, Font.NORMAL);
        Font labelFont = new Font(bfChinese, 11f, Font.NORMAL);

        // 添加标题
        addSection(document, "十一、合同书各责任方", titleFont);

        // 创建甲方表格
        PdfPTable table = new PdfPTable(2);
        table.setWidths(new float[]{35f, 65f});
        table.setWidthPercentage(100);


        addCell(table, "甲方（项目下达单位）", null, null, labelFont, null, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);
        addCell(table, "云南省卫生健康委员会", null, null, labelFont, null, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);

        String commonTerms = "\n\n\n\n\n\n\n"
                + " 经办人签字:                          法定代表人（或授权代表）： \n\n"
                + "           年  月   日                                      年  月   日 ";
        Paragraph para = new Paragraph(commonTerms, normalFont);
        para.setAlignment(Element.ALIGN_LEFT);
        para.setSpacingBefore(40f);
//      para.setSpacingAfter(15f);

        PdfPCell timeCell = new PdfPCell(para);
        timeCell.setMinimumHeight(210f);
        timeCell.setColspan(2);
//      timeCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        timeCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        table.addCell(timeCell);

        addCell(table, "乙方（项目承担单位）", null, null, labelFont, null, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);
        addCell(table, dto.getAppUnitName(), null, null, labelFont, null, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);

        String terms = "\n\n\n\n\n\n"
                + " 法定代表人（或授权代表）：    项目负责人（签字）：     财务负责人（签字）：\n\n"
                + "               年   月   日           年   月   日             年   月   日 \n\n"
                + " 开户银行：\n\n"
                + " 账号名称：\n\n"
                + " 银行账号：\n\n"
                + "                                                   （承担单位公章）\n\n"
                + "                                                     年   月   日  \n\n";
        Paragraph ph = new Paragraph(terms, normalFont);
        ph.setAlignment(Element.ALIGN_LEFT);
        ph.setSpacingBefore(40f);

        PdfPCell cell = new PdfPCell(ph);
        cell.setMinimumHeight(300f);
        cell.setColspan(2);
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        table.addCell(cell);

        document.add(table);
    }

    private static String numberTo(int number) {
        char[] cs = "零一二三四五六七八九".toCharArray();
        String temp = "";
        while (number > 0) {
            temp += cs[number % 10];
            number /= 10;
        }
        return temp;

    }

    /**
     * 水印页面事件
     */
    private static class WatermarkPageEvent extends PdfPageEventHelper {
        private String watermarkText;
        private BaseFont baseFont;

        public WatermarkPageEvent(String watermarkText, BaseFont baseFont) {
            this.watermarkText = watermarkText;
            this.baseFont = baseFont;
        }

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            try {
                PdfContentByte canvas = writer.getDirectContentUnder();
                Rectangle pageSize = document.getPageSize();
                float width = pageSize.getWidth();
                float height = pageSize.getHeight();

                // 设置水印字体
                canvas.saveState();
                canvas.beginText();
                canvas.setFontAndSize(baseFont, 30);  // 减小字体大小
                canvas.setGrayFill(0.9f);

                // 计算水印间距
                float xStep = width / 2;  // 水平间距
                float yStep = height / 3;  // 垂直间距

                // 在页面上添加多个水印
                for (float y = yStep / 2; y < height; y += yStep) {
                    for (float x = xStep / 2; x < width; x += xStep) {
                        canvas.showTextAligned(Element.ALIGN_CENTER,
                                watermarkText,
                                x,
                                y,
                                45);
                    }
                }

                canvas.endText();
                canvas.restoreState();

                // 添加页码
                PdfContentByte canvasOver = writer.getDirectContent();
                canvasOver.saveState();
                canvasOver.beginText();
                canvasOver.setFontAndSize(baseFont, 12);  // 设置页码字体大小
                canvasOver.setColorFill(BaseColor.BLACK);

                // 页码文本
                String text = String.format("- %d -", writer.getPageNumber());

                // 在页面底部居中添加页码
                canvasOver.showTextAligned(Element.ALIGN_CENTER,
                        text,
                        width / 2,    // 页面中心
                        15,          // 距离底部15单位，降低页码位置
                        0);          // 不旋转

                canvasOver.endText();
                canvasOver.restoreState();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static void addTablePageCell(PdfPTable table, String label, Integer labelColspan, String value, Integer valueColspan, Font font) {
        PdfPCell labelCell = new PdfPCell(new Phrase(label, font));
        // 设置标签单元格样式
        labelCell.setMinimumHeight(36f); // 增加行高
        labelCell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        labelCell.setHorizontalAlignment(Element.ALIGN_LEFT); // 改为左对齐
        if (Objects.nonNull(labelColspan))
            labelCell.setColspan(labelColspan);
        labelCell.setBorder(Rectangle.NO_BORDER);
        table.addCell(labelCell);

        PdfPCell valueCell = new PdfPCell(new Phrase(value != null ? value : "", font));
        valueCell.setPadding(5f);
        valueCell.setMinimumHeight(36f); // 增加行高
        valueCell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        if (Objects.nonNull(valueColspan))
            valueCell.setColspan(valueColspan);
        // 只保留下边框
        valueCell.setBorder(Rectangle.BOTTOM);
        table.addCell(valueCell);
    }

    private static void addValueCell(PdfPTable table, String label, Integer labelColspan, String value, Integer valueColspan, Font font, Float height, Integer vertical, Integer horizontal) {
        addCell(table, label, labelColspan, null, font, height, vertical, horizontal);
        addCell(table, value, valueColspan, null, font, height, vertical, horizontal);
    }

    private static void addCell(PdfPTable table, Object value, Integer valueColspan, Integer valueRowspan, Font font, Float height, Integer vertical, Integer horizontal) {
        if (Objects.isNull(height))
            height = 25.5f;
        if (Objects.isNull(vertical))
            vertical = Element.ALIGN_MIDDLE;
        if (Objects.isNull(horizontal))
            horizontal = Element.ALIGN_LEFT;
        PdfPCell valueCell = new PdfPCell(new Phrase(value != null ? value.toString() : "", font));
        if (Objects.nonNull(valueRowspan))
            valueCell.setRowspan(valueRowspan);
        if (Objects.nonNull(valueColspan))
            valueCell.setColspan(valueColspan);
        valueCell.setCellEvent(new UniformBorderEvent());
        valueCell.setPadding(5f);
        valueCell.setMinimumHeight(height);
        valueCell.setVerticalAlignment(vertical);
        valueCell.setHorizontalAlignment(horizontal);
        // 设置边框宽度
        valueCell.setBorderColor(new BaseColor(0, 0, 0));
//      valueCell.setBorderWidth(0.5f); // 设置边框宽度
        table.addCell(valueCell);
    }

    private static void addLabelValueRow(PdfPTable table, String label, String value, int valueColspan, Font titleFont, Font contentFont) {
        PdfPCell labelCell = new PdfPCell(new Phrase(label, titleFont));
        labelCell.setMinimumHeight(25f);
        labelCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        labelCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(labelCell);

        PdfPCell valueCell = new PdfPCell(new Phrase(value != null ? value : "", contentFont));
        valueCell.setMinimumHeight(25f);
        valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell.setColspan(valueColspan);
        table.addCell(valueCell);
    }

    private static void addTableContentCell(PdfPTable table, String label, String value, Integer valueColspan, Font font, Float height) {
        if (Objects.isNull(height))
            height = 25.5f;
        Paragraph para = new Paragraph(label + (label.equals("") ? "" : "\n") + value, font);
        para.setAlignment(Element.ALIGN_LEFT);
        para.setLeading(24f); // 设置行间距
        PdfPCell valueCell = new PdfPCell(para);
        valueCell.setMinimumHeight(height);
        valueCell.setVerticalAlignment(Element.ALIGN_TOP);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell.setCellEvent(new UniformBorderEvent());
//      valueCell.setBorderWidth(0.5f); // 设置边框宽度
        if (Objects.nonNull(valueColspan))
            valueCell.setColspan(valueColspan);
        table.addCell(valueCell);
    }

    private static BaseFont loadChineseFont(String fontName) {
        try {
            if ("linux".equals(getCurrentOperatingSystem())) {
                if (fontName.toLowerCase().endsWith(".ttc"))
                    return BaseFont.createFont("/usr/share/fonts/" + fontName + ",0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                else
                    return BaseFont.createFont("/usr/share/fonts/" + fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            } else {
                if (fontName.toLowerCase().endsWith(".ttc"))
                    return BaseFont.createFont("c:/Windows/Fonts/" + fontName + ",0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                else
                    return BaseFont.createFont("c:/Windows/Fonts/" + fontName, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            }
        } catch (Exception e) {
            throw new RuntimeException("加载字体文件失败，请确保系统中存在字体文件 " + fontName + "：" + e.getMessage(), e);
        }
    }

    private static void addSection(Document document, String title, Font font) throws DocumentException {
        Paragraph section = new Paragraph(title, font);
        section.setSpacingBefore(15);
        section.setSpacingAfter(10);
        document.add(section);
    }
}
