# 报表取数服务插件 — C#（SysReportBaseService）

```csharp
using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts.Report;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.Core.Report.PlugIn;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using static Kingdee.BOS.Core.Enums.BOSEnums;

namespace Kingdee.MyProject.Report
{
    [Description("报表取数服务插件"), HotUpdate]
    public class MyReportService : SysReportBaseService
    {
        public override void Initialize()
        {
            base.Initialize();
            this.ReportProperty.ReportType = ReportType.REPORTTYPE_NORMAL;
            this.IsCreateTempTableByPlugin = true;
            this.ReportProperty.IsGroupSummary = true;
            this.ReportProperty.IdentityFieldName = "FIDENTITYID";
            this.ReportProperty.PrimaryKeyFieldName = "FID";
            this.ReportProperty.IsUIDesignerColumns = false;

            // 精度控制
            var fields = new List<DecimalControlField>
            {
                new DecimalControlField { ByDecimalControlFieldName = "FQty", DecimalControlFieldName = "FQTYPrecision" },
                new DecimalControlField { ByDecimalControlFieldName = "FAmount", DecimalControlFieldName = "FQTYPrecision" }
            };
            base.ReportProperty.DecimalControlFieldList = fields;
        }

        public override ReportHeader GetReportHeaders(IRptParams filter)
        {
            ReportHeader header = base.GetReportHeaders(filter);
            header.AddChild("FMaterialNumber", new LocaleValue("物料编码"));
            header.AddChild("FMaterialName", new LocaleValue("物料名称"));
            header.AddChild("FQty", new LocaleValue("数量"));
            header.AddChild("FAmount", new LocaleValue("金额"));

            // 动态列示例：header.AddChild("F2024_1_1", new LocaleValue("每日订单"), SqlStorageType.SqlDecimal);
            return header;
        }

        public override void BuilderReportSqlAndTempTable(IRptParams filter, string tableName)
        {
            var custFilter = filter.FilterParameter.CustomFilter;
            string sql = $@"/*dialect*/
SELECT ROW_NUMBER() OVER (ORDER BY m.FMATERIALID) AS FIDENTITYID,
    m.FMATERIALID AS FID,
    m.FNUMBER AS FMaterialNumber,
    ml.FNAME AS FMaterialName,
    SUM(e.FQty) AS FQty,
    SUM(e.FAmount) AS FAmount
INTO {tableName}
FROM T_PUR_POORDER h
INNER JOIN T_PUR_POORDERENTRY e ON e.FID = h.FID
INNER JOIN T_BD_MATERIAL m ON m.FMATERIALID = e.FMATERIALID
INNER JOIN T_BD_MATERIAL_L ml ON ml.FMATERIALID = m.FMATERIALID AND ml.FLOCALEID = 2052
WHERE h.FDOCUMENTSTATUS = 'C'
GROUP BY m.FMATERIALID, m.FNUMBER, ml.FNAME
";
            DBUtils.Execute(this.Context, sql);
        }

        public override ReportTitles GetReportTitles(IRptParams filter)
        {
            var titles = new ReportTitles();
            var custFilter = filter.FilterParameter.CustomFilter;
            var orgObj = custFilter?["F_OrgId"] as DynamicObject;
            if (orgObj != null)
                titles.AddTitle("F_OrgId", Convert.ToString(orgObj["Name"]));
            return titles;
        }

        public override List<SummaryField> GetSummaryColumnInfo(IRptParams filter)
        {
            return new List<SummaryField>
            {
                new SummaryField("FQty", Enu_SummaryType.SUM),
                new SummaryField("FAmount", Enu_SummaryType.SUM)
            };
        }

        public override void CloseReport()
        {
            this.DropTempTable();
        }
    }
}
```

**AbstractSysReportServicePlugIn / SysReportBaseService 全部事件（反编译 Kingdee.BOS.Core.dll）：**
**Initialize()** / **GetReportHeaders**(IRptParams) / **GetReportTitles**(IRptParams) / **BuilderReportSqlAndTempTable**(IRptParams, String) / **GetSummaryColumnInfo**(IRptParams) → List<SummaryField> / **CloseReport()** / CloseReportInstance() / DropTempTable() / GetRowsCount(IRptParams) → int / GetTableName() → string / GetReportHeadersForDesigner(IRptParams) / GetList(IRptParams) → DataTable / GetTreeNodes(IRptParams) → List<TreeNode> / GetOrgIdList(IRptParams) → List<long> / ExportMoveRptAllPage(IRptParams) → MoveRptAllPage / GetListAndReportData(IRptParams) → IMoveReport

ReportProperty 和 IsCreateTempTableByPlugin 在 SysReportBaseService 中（继承链：SysReportBaseService → AbstractSysReportServicePlugIn）。

**源码参考：** `博瑞报表/` — SaleReportServicePlugin.cs, DefectReasonAnalysisRptExt.cs, PurchasePaymentReportServicePlugin.cs
