package com.yiboshi.science.utils;

import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
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 java.io.*;
import java.util.Objects;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ProjectInfoToPDF {

    /**
     * 生成项目申请书和合同书PDF
     * @param project 项目信息
     * @return 生成的PDF文件字节数组
     */
    public static byte[] generateProjectPDF(ComProjectDTO project, List<SystemParameter> projAttributeList) throws DocumentException, IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Document document = new Document(PageSize.A4);
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        
        try {
            // 文件水印
            String watermark = project.getAppNo();
            if (project.getProjState() >= CommonEnum.projState.pass.getCode()) {
                watermark = project.getProjNo();
            }
            
            // 宋体
            BaseFont bfChinese = loadChineseFont("simsun.ttc");
            // 仿宋
            BaseFont fsChinese = loadChineseFont("simfang.ttf");
            // WINGDNG2
            BaseFont WINGDNG2 = loadChineseFont("WINGDNG2.ttf");

            // 添加水印
            writer.setPageEvent(new WatermarkPageEvent(watermark, fsChinese));

            document.open();

            Font normalFont = new Font(bfChinese, 12, Font.NORMAL);
            Font boldFont = new Font(bfChinese, 12, Font.BOLD);

            //首页内容
            FirstPageInfo(document, project, bfChinese, fsChinese);
            
            // 添加新页面
            document.newPage();

            // 添加项目内容章节
            addSection(document, "一、项目基本情况", boldFont);
            addProjectBasicTable(document, project, bfChinese, fsChinese);  // 添加项目基本信息表格
            
            // 添加横向页面
            document.setPageSize(PageSize.A4.rotate());
            document.newPage();

            // 添加项目组主要成员表格
            addProjectMembersTable(document, project, bfChinese, fsChinese);
            document.newPage();

            // 添加项目绩效目标表
            addProjectKPITable(document, project, projAttributeList, bfChinese, fsChinese, WINGDNG2);

            // 恢复为纵向页面
            document.setPageSize(PageSize.A4);
            document.newPage();

            // 项目经费预算表
            addProjectBudgetTable(document, project, bfChinese, fsChinese);

            // 插入申请书正文PDF
            if (null != project.getConvertUrl() && !project.getConvertUrl().trim().isEmpty()) {
                InsertPdfContent(document, "申请书正文", System.getProperty("user.dir") + project.getConvertUrl(), writer);
            }

            // 加载项目组成员简历
            List<ComProjectMembersDTO> MemberList = project.getMembers();
            if (null != MemberList && MemberList.size() > 0) {
                LoadProjectMember(document, MemberList, writer);
            }

            // 添加新页面
            document.newPage();

            addSection(document, "二、主要技术指标", boldFont);
            addContent(document, project.getTechnologyTarget(), normalFont);

            addSection(document, "三、主要经济指标", boldFont);
            addContent(document, project.getEconomyTarget(), normalFont);

            addSection(document, "四、项目实施中形成的示范基地、中试线、生产线及其规模等", boldFont);
            addContent(document, project.getAchievementTarget(), normalFont);

            addSection(document, "五、科技报告考核指标", boldFont);
            addContent(document, project.getTechnologyReportsTarget(), normalFont);

            addSection(document, "六、其他应考核的指标", boldFont);
            addContent(document, project.getOtherTarget(), normalFont);

            // 添加签字栏
            addSignatureSection(document, normalFont);

            document.close();
            return baos.toByteArray();
        } finally {
            if (document.isOpen()) {
                document.close();
            }
            baos.close();
        }
    }

    /**
     * 加载中文字体
     * @param fontName 字体文件名
     * @return BaseFont 中文字体
     * @throws RuntimeException 加载字体失败时抛出异常
     */
    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);
            }
//            // 从资源文件夹加载字体
//            String path = ProjectInfoToPDF.class.getResource(fontPath).getPath();
//
//            // 根据字体文件类型使用不同的加载方式
//            if (fontPath.toLowerCase().endsWith(".ttc")) {
//                return BaseFont.createFont(path + ",0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//            } else {
//                return BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//            }
        } catch (Exception e) {
            throw new RuntimeException("加载字体文件失败,请确保系统中存在字体文件 " + fontName + ":" + e.getMessage(), e);
        }
    }

    public static String getCurrentOperatingSystem() {
        String os = System.getProperty("os.name").toLowerCase();
        //System.out.println("---------当前操作系统是-----------" + os);
        return os;
    }

    /**
     * 首页项目信息
     * @param document
     * @param project
     * @param bfChinese
     * @param fsChinese
     * @return
     * @throws DocumentException
     */
    private static Document FirstPageInfo(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {

        Font titleFont = new Font(bfChinese, 20, Font.BOLD);
        Font normalFont = new Font(bfChinese, 12, Font.NORMAL);
        Font labelFont = new Font(fsChinese, 16, Font.NORMAL);
        Font valueFont = new Font(bfChinese, 16, Font.NORMAL);

        // 添加项目编号到左上角
        Paragraph projNo;
        if (Objects.nonNull(project.getProjNo())) {
            Chunk text = new Chunk("项目编号:", normalFont);
            Chunk number = new Chunk(project.getProjNo(), normalFont);
            number.setUnderline(0.1f, -2f); // 设置下划线
            projNo = new Paragraph();
            projNo.add(text);
            projNo.add(number);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
        } else {
            Chunk text = new Chunk("项目编号:", normalFont);
            Chunk underline = new Chunk("                    ", normalFont);
            underline.setUnderline(0.1f, -2f); // 设置下划线
            projNo = new Paragraph();
            projNo.add(text);
            projNo.add(underline);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
            projNo.add(Chunk.NEWLINE);
        }
        projNo.setAlignment(Element.ALIGN_LEFT);
        projNo.setSpacingAfter(50f);
        document.add(projNo);

        // 添加标题
        Paragraph title = new Paragraph("省级临床医学中心科研项目申请书", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(50f);  // 增加标题后的间距
        document.add(title);

        // 添加项目基本信息表格
        PdfPTable table = new PdfPTable(2);
        table.setWidthPercentage(95);
        table.setSpacingBefore(50f);  // 增加表格前的间距
        table.setSpacingAfter(10f);
        table.setHorizontalAlignment(Element.ALIGN_LEFT);  // 设置表格左对齐
        
        // 设置列宽度
        float[] columnWidths = {0.35f, 0.65f};
        table.setWidths(columnWidths);

        // 添加表格内容
        addTableRow(table, "项目名称:", project.getProjName(), labelFont, valueFont);
        addTableRow(table, "申报单位:", project.getAppUnitName(), labelFont, valueFont);
        addTableRow(table, "推荐部门(丙方):", "", labelFont, valueFont);
        addTableRow(table, "项目负责人:", project.getAppPersonName(), labelFont, valueFont);
        addTableRow(table, "联系电话:", project.getMobile(), labelFont, valueFont);
        addTableRow(table, "起止年限:", DateUtils.formatDateRange(project.getStartDate(), 1) + "至" + DateUtils.formatDateRange(project.getEndDate(), 1), labelFont, valueFont);
        addTableRow(table, "填报日期:", DateUtils.formatDateRange(project.getCreated(), 2), labelFont, valueFont);
        document.add(table);

        return document;
    }

    /**
     * 添加首页项目表格信息
     * @param table
     * @param label
     * @param value
     * @param labelFont
     * @param valueFont
     */
    private static void addTableRow(PdfPTable table, String label, String value, Font labelFont, Font valueFont) {
        // 标签单元格
        PdfPCell labelCell = new PdfPCell(new Phrase(label, labelFont));
        labelCell.setMinimumHeight(28f);
        labelCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        labelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
        labelCell.setPaddingRight(5f);
        labelCell.setBorder(Rectangle.NO_BORDER);
        
        // 值单元格
        Phrase valuePhrase;
        if (value != null && !value.trim().isEmpty()) {
            valuePhrase = new Phrase(value, valueFont);
        } else {
            valuePhrase = new Phrase(" ", valueFont); // 空值时使用一个空格
        }
        
        PdfPCell valueCell = new PdfPCell(valuePhrase);
        valueCell.setMinimumHeight(28f);
        valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);  // 修改为左对齐
        valueCell.setPaddingLeft(5f);
        valueCell.setPaddingRight(10f);
        valueCell.setBorder(Rectangle.NO_BORDER);
        
        // 添加自定义事件来绘制下划线
        valueCell.setCellEvent(new PdfPCellEvent() {
            public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
                PdfContentByte cb = canvases[PdfPTable.LINECANVAS];
                cb.setLineWidth(0.5f);
                float y = position.getBottom() + 2; // 调整下划线位置
                cb.moveTo(position.getLeft(), y);
                cb.lineTo(position.getRight(), y);
                cb.stroke();
            }
        });
        
        table.addCell(labelCell);
        table.addCell(valueCell);
    }

    /**
     * 项目基本信息
     * @param document
     * @param project
     * @param bfChinese
     * @param fsChinese
     * @throws DocumentException
     */
    private static void addProjectBasicTable(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        Font labelFont = new Font(bfChinese, 12, Font.NORMAL);
        Font valueFont = new Font(fsChinese, 12, Font.NORMAL);
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);

        // 创建一个大表格
        PdfPTable mainTable = new PdfPTable(1);  // 单列表格
        mainTable.setWidthPercentage(95);
        mainTable.setSpacingBefore(10f);

        // 申请人信息部分
        PdfPTable personTable = new PdfPTable(9);  // 9列,第一列用于标题
        float[] personWidths = {1f, 1.5f, 2f, 1f, 2f, 1.5f, 2f, 2f, 2f};  // 调整第一列宽度
        personTable.setWidths(personWidths);
        
        // 申请人信息标题行
        PdfPCell titleCell = new PdfPCell(new Phrase("申\n请\n人\n信\n息", titleFont));
        titleCell.setRowspan(6);  // 合并6行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(150f);  // 调整高度以适应内容
        personTable.addCell(titleCell);
        
        // 第一行
        addBasicTableCell(personTable, "姓    名", project.getAppPersonName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "性别", project.getSex(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "出生年月", DateUtils.formatDateRange(project.getBirthday(), 1), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "民族", project.getNationName(), 2, labelFont, valueFont);
        
        // 第二行
        addBasicTableCell(personTable, "学    位", project.getDegreeName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "职称", project.getTitleName(), 2, labelFont, valueFont);
        addBasicTableCell(personTable, "每年工作时间(月)", project.getJobTime().toString(), 4, labelFont, valueFont);
        
        // 第三行
        addBasicTableCell(personTable, "电    话", project.getMobile(), 4, labelFont, valueFont);
        addBasicTableCell(personTable, "电子邮箱", project.getEmail(), 4, labelFont, valueFont);
        
        // 第四行
        addBasicTableCell(personTable, "个人通讯地址", project.getAddress(), 8, labelFont, valueFont);
        
        // 第五行
        addBasicTableCell(personTable, "工作单位", project.getAppUnitName(), 8, labelFont, valueFont);
        
        // 第六行
        addBasicTableCell(personTable, "主要研究领域", project.getMainResearchAreas(), 8, labelFont, valueFont);

        // 将申请人信息表格添加到主表格
        PdfPCell personCell = new PdfPCell(personTable);
        personCell.setPadding(0);
        personCell.setBorder(Rectangle.BOX);
        mainTable.addCell(personCell);
        
        // 申请单位信息部分
        PdfPTable unitTable = new PdfPTable(5);  // 5列,第一列用于标题
        float[] unitWidths = {1.2f, 3f, 5f, 3f, 5f};  // 调整所有列的比例,保持第一列宽度一致
        unitTable.setWidths(unitWidths);
        
        // 申请单位信息标题行
        titleCell = new PdfPCell(new Phrase("申\n请\n单\n位\n信\n息", titleFont));
        titleCell.setRowspan(5);  // 合并5行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(100f);
        unitTable.addCell(titleCell);
        
        // 单位信息内容
        addBasicTableCell(unitTable, "单位名称", project.getAppUnitName(), 4, labelFont, valueFont);
        addBasicTableCell(unitTable, "联系人", project.getUnitLinkName(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "电话", project.getUnitLinkMobile(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "电子信箱", project.getUnitLinkEmail(), 2, labelFont, valueFont);
        addBasicTableCell(unitTable, "传真", project.getUnitLinkFax(), 2, labelFont, valueFont);

        // 将申请单位信息表格添加到主表格
        PdfPCell unitCell = new PdfPCell(unitTable);
        unitCell.setPadding(0);
        unitCell.setBorder(Rectangle.BOX);
        mainTable.addCell(unitCell);
        
        // 项目基本情况部分
        PdfPTable projTable = new PdfPTable(5);  // 5列,第一列用于标题
        float[] projWidths = {1.2f, 3f, 5f, 3f, 5f};  // 与申请单位信息表格使用相同的比例
        projTable.setWidths(projWidths);
        
        // 项目基本情况标题行
        titleCell = new PdfPCell(new Phrase("项\n目\n基\n本\n信\n息", titleFont));
        titleCell.setRowspan(8);  // 合并8行
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        titleCell.setMinimumHeight(200f);
        projTable.addCell(titleCell);
        
        // 项目基本情况内容
        addBasicTableCell(projTable, "项目名称", project.getProjName(), 4, labelFont, valueFont);
        addBasicTableCell(projTable, "学科代码", project.getKnowledgeName(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "选题范围", project.getSubjectScope(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目类别", project.getProjClassName(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "研究期限", DateUtils.formatDateRange(project.getStartDate(), 1), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目总经费(万元)", project.getTotalFunding().toString(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "申请经费", project.getGovFunding().toString(), 2, labelFont, valueFont);
        addBasicTableCell(projTable, "项目摘要", project.getProjAbstract(), 4, labelFont, valueFont);
        addBasicTableCell(projTable, "关键词", project.getProjKeywords(), 4, labelFont, valueFont);

        // 将项目基本情况表格添加到主表格
        PdfPCell projCell = new PdfPCell(projTable);
        projCell.setPadding(0);
        projCell.setBorder(Rectangle.BOX);
        mainTable.addCell(projCell);

        document.add(mainTable);
    }

    /**
     * 添加基本信息表格单元格
     * @param table
     * @param label
     * @param value
     * @param colspan
     * @param labelFont
     * @param valueFont
     */
    private static void addBasicTableCell(PdfPTable table, String label, String value, int colspan, Font labelFont, Font valueFont) {
        PdfPCell labelCell = new PdfPCell(new Phrase(label, labelFont));
        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 : "", valueFont));
        valueCell.setMinimumHeight(25f);
        valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        valueCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell.setColspan(colspan - 1);
        table.addCell(valueCell);
    }

    /**
     * 添加项目组主要成员表格
     * @param document PDF文档
     * @param project 项目信息
     * @param bfChinese 宋体字体
     * @param fsChinese 仿宋字体
     * @throws DocumentException
     */
    private static void addProjectMembersTable(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);
        Font contentFont = new Font(bfChinese, 12, Font.NORMAL);
        
        // 添加表格标题
        Paragraph title = new Paragraph("项目组主要成员", titleFont);
        title.add(new Chunk(" (注:不包括项目申请人)", contentFont));
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10f);
        document.add(title);

        // 创建表格
        PdfPTable table = new PdfPTable(12);  // 12列
        table.setWidthPercentage(98);
        
        // 设置列宽度比例
        float[] widths = {0.5f, 1f, 1f, 0.8f, 0.8f, 0.8f, 2f, 0.8f, 1.2f, 1f, 1.2f, 1f};
        table.setWidths(widths);

        // 添加表头
        String[] headers = {"序号", "姓名", "出生年月", "性别", "职称", "学位", "工作单位", "电话", "电子邮箱", "证件号码", "项目分工", "每年工作时间(月)"};
        for (String header : headers) {
            PdfPCell cell = new PdfPCell(new Phrase(header, contentFont));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setMinimumHeight(25f);
            table.addCell(cell);
        }

        List<ComProjectMembersDTO> members = project.getMembers();
        // 添加成员数据
        if (members != null && !members.isEmpty()) {
            int index = 1;
            for (ComProjectMembersDTO member : members) {
                // 序号
                addCenterCell(table, String.valueOf(index++), contentFont);
                // 姓名
                addCenterCell(table, member.getName(), contentFont);
                // 出生年月
                addCenterCell(table, DateUtils.formatDateRange(member.getBirthday(), 1), contentFont);
                // 性别
                addCenterCell(table, member.getSex(), contentFont);
                // 职称
                addCenterCell(table, member.getTitleName(), contentFont);
                // 学位
                addCenterCell(table, member.getDegreeName(), contentFont);
                // 工作单位
                addCenterCell(table, member.getWorkUnit(), contentFont);
                // 电话
                addCenterCell(table, member.getMobile(), contentFont);
                // 电子邮箱
                addCenterCell(table, member.getEmail(), contentFont);
                // 证件号码
                addCenterCell(table, member.getCertId(), contentFont);
                // 项目分工
                addCenterCell(table, member.getProjWork(), contentFont);
                // 每年工作时间
                addCenterCell(table, member.getForMonths().toString(), contentFont);
            }
        }

        // 如果成员数量少于9个,添加空行到9行
        int emptyRows = 9 - (members != null ? members.size() : 0);
        for (int i = 0; i < emptyRows; i++) {
            for (int j = 0; j < 12; j++) {
                addCenterCell(table, "", contentFont);
            }
        }

        document.add(table);

        // 项目组成员统计表格
        PdfPTable statsTable = new PdfPTable(7);  // 7列
        statsTable.setWidthPercentage(98);
        statsTable.setSpacingBefore(20f);  // 与上表格保持间距
        
        // 设置列宽度比例
        float[] statsWidths = {1f, 1f, 1f, 1f, 1f, 1f, 1f};
        statsTable.setWidths(statsWidths);

        // 添加表头
        String[] statsHeaders = {"总人数", "高级", "中级", "初级", "博士后", "博士生", "硕士生"};
        for (String header : statsHeaders) {
            PdfPCell cell = new PdfPCell(new Phrase(header, contentFont));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setMinimumHeight(25f);
            statsTable.addCell(cell);
        }

        // 添加数据行
        addCenterCell(statsTable, project.getMemCount() != null ? project.getMemCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemHighCount() != null ? project.getMemHighCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemMiddleCount() != null ? project.getMemMiddleCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemLowCount() != null ? project.getMemLowCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemBshCount() != null ? project.getMemBshCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemBsCount() != null ? project.getMemBsCount().toString() : "", contentFont);
        addCenterCell(statsTable, project.getMemSsCount() != null ? project.getMemSsCount().toString() : "", contentFont);

        document.add(statsTable);
    }

    /**
     * 添加项目绩效目标表
     * @param document PDF文档
     * @param project 项目信息
     * @param bfChinese 宋体字体
     * @param fsChinese 仿宋字体
     * @throws DocumentException
     */
    private static void addProjectKPITable(Document document, ComProjectDTO project, List<SystemParameter> projAttributeList, BaseFont bfChinese, BaseFont fsChinese, BaseFont WINGDNG2) throws DocumentException, IOException {
        ProjectKPIStatisticDTO kpitDTO = project.getProjectKPI();
        List<ComProjectKpitDTO> detail = project.getProjectKPI().getThreeLevel();

        Font titleFont = new Font(bfChinese, 12, Font.BOLD);
        Font contentFont = new Font(bfChinese, 12, Font.NORMAL);
        Font wingdng2Font = new Font(WINGDNG2, 12, Font.NORMAL);
        
        // 添加表格标题
        Paragraph title = new Paragraph("绩效目标表", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10f);
        document.add(title);

        // 创建主表格
        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(), 5, titleFont, contentFont);

        // 主管处室和实施单位
        addLabelValueRow(mainTable, "主管处室", kpitDTO.getManagerDept(), 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);
    }

    /**
     * 项目经费预算表
     * @param document
     * @param project
     * @param bfChinese
     * @param fsChinese
     * @throws DocumentException
     */
    private static void addProjectBudgetTable(Document document, ComProjectDTO project, BaseFont bfChinese, BaseFont fsChinese) throws DocumentException {
        Font titleFont = new Font(bfChinese, 12, Font.BOLD);
        Font contentFont = new Font(bfChinese, 12, Font.NORMAL);
        Font detailFont = new Font(fsChinese, 9, Font.NORMAL);

        // 添加表格标题
        Paragraph title = new Paragraph("项目经费预算表", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10f);
        document.add(title);

        // 添加金额单位说明
        Paragraph unit = new Paragraph("金额单位:万元(保留两位小数)", detailFont);
        unit.setAlignment(Element.ALIGN_RIGHT);
        unit.setSpacingAfter(10f);
        document.add(unit);

        // 创建预算表格
        PdfPTable budgetTable = new PdfPTable(5);
        budgetTable.setWidthPercentage(98);
        float[] widths = {2f, 0.5f, 0.5f, 0.5f, 1f};
        budgetTable.setWidths(widths);

        // 添加表头
        String[] headers = {"预算科目", "总预算数", "财政资金", "自筹资金", "备注"};
        for (String header : headers) {
            addTitleCell(budgetTable, header, 0, 0, titleFont);
        }

        for (ComProjectBudgetDTO dto : project.getBudget()) {
            if (dto.getBudgetId().toLowerCase().equals("3b1f57d3-6aec-4129-aef5-702a1accfe01") || dto.getBudgetId().toLowerCase().equals("3b1f57d3-6aec-4129-aef5-702a1accfe08"))
                addBudgetTitleCell(budgetTable, dto.getBudgetName(), titleFont, Element.ALIGN_LEFT, 0, 0);
            else
                addBudgetTitleCell(budgetTable, dto.getBudgetName(), contentFont, Element.ALIGN_LEFT, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getTotalBudget().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getApplyFunds().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getSelfFunds().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getCalculationBasis(), contentFont, Element.ALIGN_LEFT, 0, 0);
        }

        addBudgetTitleCell(budgetTable, "三、分年度用款计划", titleFont, Element.ALIGN_LEFT, 5, 0);
        addBudgetTitleCell(budgetTable, "年度", titleFont, Element.ALIGN_CENTER, 0, 0);
        addBudgetTitleCell(budgetTable, "第一年", titleFont, Element.ALIGN_CENTER, 0, 0);
        addBudgetTitleCell(budgetTable, "第二年", titleFont, Element.ALIGN_CENTER, 0, 0);
        addBudgetTitleCell(budgetTable, "第三年", titleFont, Element.ALIGN_CENTER, 0, 0);
        addBudgetTitleCell(budgetTable, "合计", titleFont, Element.ALIGN_CENTER, 0, 0);

        for (ComProjectFundPlanDTO dto : project.getFundPlan()) {
            addBudgetTitleCell(budgetTable, dto.getFundName(), titleFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getYearValue1().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getYearValue2().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getYearValue3().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
            addBudgetTitleCell(budgetTable, dto.getTotalAmount().toString(), contentFont, Element.ALIGN_CENTER, 0, 0);
        }

        document.add(budgetTable);
    }

    private static void addBudgetTitleCell(PdfPTable table, String title, Font contentFont, int HorizontalAlignment, int colSpan, int rowSpan) {
        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(HorizontalAlignment);
        table.addCell(titleCell);
    }

    /**
     * 添加标签值行
     */
    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 addCenterCell(PdfPTable table, String content, Font font) {
        PdfPCell cell = new PdfPCell(new Phrase(content != null ? content : "", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setMinimumHeight(25f);
        table.addCell(cell);
    }

    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);
    }

    private static void addContent(Document document, String content, Font font) throws DocumentException {
        if (content != null) {
            Paragraph paragraph = new Paragraph(content, font);
            paragraph.setIndentationLeft(20);
            paragraph.setSpacingAfter(10);
            document.add(paragraph);
        }
    }

    private static void addSignatureSection(Document document, Font font) throws DocumentException {
        Paragraph signature = new Paragraph("\n\n", font);
        signature.add(new Chunk("申请人签字:", font));
        signature.add(new Chunk("                            ", font));
        signature.add(new Chunk("日期:", font));
        signature.add(new Chunk("                            ", font));
        signature.setAlignment(Element.ALIGN_RIGHT);
        signature.setSpacingBefore(50);
        document.add(signature);

        Paragraph unitSignature = new Paragraph("\n", font);
        unitSignature.add(new Chunk("申请单位(盖章):", font));
        unitSignature.add(new Chunk("                            ", font));
        unitSignature.add(new Chunk("日期:", font));
        unitSignature.add(new Chunk("                            ", font));
        unitSignature.setAlignment(Element.ALIGN_RIGHT);
        unitSignature.setSpacingBefore(30);
        document.add(unitSignature);
    }

    /**
     * 水印页面事件
     */
    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();
            }
        }
    }

    /**
     * 插入PDF文件到指定位置
     * @param document 目标文档
     * @param titleName 标题名称
     * @param pdfPath 要插入的PDF文件路径
     * @throws DocumentException
     * @throws IOException
     */
    private static void InsertPdfContent(Document document, String titleName, String pdfPath, PdfWriter writer) throws DocumentException, IOException {
        PdfReader reader = null;
        try {
            if (Objects.nonNull(titleName)) {
                // 添加标题
                Font titleFont = new Font(BaseFont.createFont(), 12, Font.BOLD);
                Paragraph title = new Paragraph(titleName, titleFont);
                title.setAlignment(Element.ALIGN_CENTER);
                title.setSpacingAfter(20f);
                document.add(title);
            }

            // 读取PDF文件内容
            byte[] pdfBytes = readPdfToBytes(pdfPath);
            
            // 创建PdfReader
            reader = new PdfReader(pdfBytes);
            
            // 获取PDF页数
            int totalPages = reader.getNumberOfPages();

            // 复制每一页
            for (int i = 1; i <= totalPages; i++) {
                document.newPage();
                PdfImportedPage page = writer.getImportedPage(reader, i);
                PdfContentByte cb = writer.getDirectContent();
                cb.addTemplate(page, 0, 0);
            }
        } catch (Exception e) {
            System.out.println("插入PDF文件失败: " + e.getMessage());
            e.printStackTrace();
            throw e;  // 重新抛出异常以确保错误被正确处理
        }
        // 不在这里关闭reader,让它在document关闭时自动关闭
    }

    /**
     * 加载项目组成员简历
     * @param document PDF文档
     * @param MemberList 成员列表
     * @param writer PDF写入器
     */
    private static void LoadProjectMember(Document document, List<ComProjectMembersDTO> MemberList, PdfWriter writer) throws DocumentException, IOException {
        // 遍历每个成员的简历
        for (ComProjectMembersDTO member : MemberList) {
            if (Objects.nonNull(member.getFileId())) {
                InsertPdfContent(document, "", System.getProperty("user.dir") + member.getConvertUrl(), writer);
            }
        }
    }

    /**
     * 读取PDF文件并返回字节数组
     * @param pdfPath PDF文件路径
     * @return 字节数组
     */
    private static byte[] readPdfToBytes(String pdfPath) throws IOException {
        File file = new File(pdfPath);
        if (!file.exists()) {
            throw new FileNotFoundException("PDF文件不存在: " + pdfPath);
        }
        
        try (FileInputStream fis = new FileInputStream(file)) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            return bos.toByteArray();
        }
    }
}