1、先进行主页面html构造

<!DOCTYPE html>
<!-- 抗菌药物使用统计报表
	csp:  csp/NTSC/NTSCAntiAgentStat/NTSCAntiAgentStat.csp
	js:   scripts/NTSC/NTSCAntiAgentStat/NTSCAntiAgentStat.js
-->
<html>
<!-- 验证session过期 -->
<csp:method name=OnPreHTTP arguments="" returntype=%Boolean>
    d ##Class(websys.SessionEvents).SessionExpired() q 1
</csp:method>

<head>
    <!-- iMedical版本标题 -->
    <title>
        <TRAK:TRANSLATE id=title>##(%session.Get("TITLE"))##</TRAK:TRANSLATE>
    </title>
    <TRAK:HEAD></TRAK:HEAD>
    <HISUI />
    <PHALIBV1 />
    <PHAPRINTCOM />
	<style>
		#report .kw-section-list > li{
	    	margin-right:10px;
   		}
		#report .keywords li{
			width : 180px;
		} 
	</style>
</head>

<body>
	<div class="hisui-panel" fit="true" border="false" style="padding:10px;">
		<div class="hisui-layout" data-options="fit:true">
			<div data-options="region:'west',border:false,split:true" style="width:265px;">
				<div class="hisui-panel" data-options="title:'抗菌药物监测网统计',headerCls:'panel-header-gray',fit:true,iconCls:'icon-paper'">
					<div class="hisui-layout" data-options="fit:true">
						<div data-options="region:'north',border:false" style="height:90px;">
							<table id="div-conditions" class="pha-con-table">
								<tr>
									<td class="r-label">
										<label for="startDate"><span style="color:red">*</span>#(..Get("开始日期"))#</label>
									</td>
									<td>
										<input id="startDate" class="hisui-datebox" data-pha='class:"hisui-datebox",requied:true,query:true,clear:true' style="width:160px;"/>
									</td>
								</tr>
								<tr>
									<td class="r-label">
										<label for="endDate"><span style="color:red">*</span>#(..Get("截止日期"))#</label>
									</td>
									<td>
										<input id="endDate" class="hisui-datebox" data-pha='class:"hisui-datebox",requied:true,query:true,clear:true' style="width:160px;" />
									</td>
								</tr>
							</table>
						</div>
						<div data-options="region:'center',border:false">
							<div class="pha-row" style="margin:5px 0 0 0;text-align:center;">
								<div class="pha-col" style="width:185px;">
									<div id="report"></div>
								</div>
							</div>
							<div class="pha-row" style="text-align:center;margin-top:15px;">
								<a href="#" id="btnFind" class="hisui-linkbutton" data-options="iconCls:'icon-w-find'">查询</a>
								<div class="pha-col">
									<a href="#" id="btnClear" class="hisui-linkbutton" data-options="iconCls:'icon-w-clean'">清屏</a>
								</div>
							</div>
							<div class="pha-row" style="text-align:center;margin-top:15px;">
								<a href="#" id="btnPrint" class="hisui-linkbutton" data-options="iconCls:'icon-w-print'">导出</a>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div data-options="region:'center',border:false">
				<csp:Include Page="NTSCAntiAgentStat.template.csp"></csp:Include>
			</div>
		</div>
	</div>
	<script type="text/javascript" src="../scripts/pha/in/v3/stat/com.js"></script>
	<script type="text/javascript" src="../scripts/pha/plugins/xlsx/xlsx.extendscript.js"></script>
	<script type="text/javascript" src="../scripts/pha/com/v1/js/export.js"></script>
	<script type="text/javascript" src="../scripts/NTSC/NTSCAntiAgentStat/NTSCAntiAgentStat.js"></script>
</body>
</html>

2、对主页面元素的id在js中处理,

/**
 *  抗菌药物使用统计报表
 *	csp: csp/NTSC/NTSCAntiAgentStat/NTSCAntiAgentStat.csp
 *	js: scripts/NTSC/NTSCAntiAgentStat/NTSCAntiAgentStat.js
*/
$(function() {	
  	$("#report").keywords({
	  	singleSelect:true,
       	items:[{
			text: '门急诊处方记录', 
			id: "NTSC_MJZCFJL" , 
			reportName: 'NTSC_MJZCFJL.rpx', 
			selected: true
		}, {
			text: '住院患者信息', 
			id: "NTSC_ZYHZXX" , 
			reportName: 'NTSC_ZYHZXX.rpx'
		}, {
			text: '住院诊断信息', 
			id: "NTSC_ZYZDXX" , 
			reportName: 'NTSC_ZYZDXX.rpx'
		}, {
			text: '住院医嘱信息', 
			id: "NTSC_ZYYZXX" , 
			reportName: 'NTSC_ZYYZXX.rpx'
		}, {
			text: '抗菌药物消耗情况', 
			id: "NTSC_KJYWXHQK" , 
			reportName: 'NTSC_KJYWXHQK.rpx'
		}, {
			text: '检验结果', 
			id: "NTSC_JYJG" , 
			reportName: 'NTSC_JYJG.rpx'
		}, {
			text: '微生物检验结果', 
			id: "NTSC_WSWJYJG" , 
			reportName: 'NTSC_WSWJYJG.rpx'
		}, {
			text: '检查结果', 
			id: "NTSC_JCJG" , 
			reportName: 'NTSC_JCJG.rpx'
		}, {
			text: '手术记录', 
			id: "NTSC_SSJL" , 
			reportName: 'NTSC_SSJL.rpx'
		}, {
			text: '生命体征记录', 
			id: "NTSC_SMTZJL" , 
			reportName: 'NTSC_SMTZJL.rpx'
		}]
	})
	InitEvents();
	InitConditionVal();
});

// 初始化 - 事件绑定
function InitEvents(){
	$('#btnFind').on("click", Query);
    $('#btnClear').on("click", Clear);
    $('#btnPrint').on("click", Print);
}

function InitConditionVal(){
	$('#startDate').datebox('setValue',PHA_UTIL.SysDate('t-30'));
	$('#endDate').datebox('setValue', PHA_UTIL.SysDate('t'));
	$("#report").keywords('select', 'NTSC_MJZCFJL');
}

function Query(){
	var reportObj = $('#report').keywords('getSelected');
	var title = reportObj[0].text;
	var queryId = reportObj[0].id;
	var formData = GetCondition();
	var InputStr = JSON.stringify(formData);
	STAT_COM.QueryRep(title, queryId, {InputStr: InputStr});
}

function Clear(){	
	ClearCondition();	
	STAT_COM.ClearRep();
	InitConditionVal();
}
function Print() {
    PHA.Loading('Show'); 
    var reportObj = $('#report').keywords('getSelected');
    if (!reportObj || reportObj.length === 0) {
        PHA.Loading('Hide');
        alert('请选择报表类型后再导出');
        return;
    }

    var selectedItem = reportObj[0];
    var queryId = selectedItem.id;
    var queryName = queryId.replace(/_/g, ''); // 移除下划线
    var reportText = selectedItem.text; 
    var startDate = $('#startDate').datebox('getValue');
    var endDate = $('#endDate').datebox('getValue');
    if (!startDate || !endDate) {
        PHA.Loading('Hide');
        alert('请选择开始日期和结束日期');
        return;
    }
    var queryParams = {
        QUERY: queryName, 
        startDate: startDate,
        endDate: endDate
    };
    var baseUrl = 'NTSC/NTSCAntiAgentStat/NTSCAntiAgentAction.csp';
    const urlWithParams = new URL(baseUrl, window.location.href); 
    Object.keys(queryParams).forEach(key => {
        urlWithParams.searchParams.append(key, queryParams[key]);
    });

    // 发起请求
    fetch(urlWithParams.toString(), {
        method: 'GET',
        headers: { 'Accept': 'application/json' }
    })
    .then(response => {
        if (!response.ok) throw new Error(`请求失败: ${response.statusText}`);
        return response.json();
    })
    .then(data => {
        PHA.Loading('Hide');
        // 验证数据格式
        if (!data || !data.cols || !data.rows) {
            alert('导出数据格式错误,请联系管理员');
            return;
        }
        var titleObj = {};
        data.cols.forEach(col => {
            if (col.ifExport === false) return;
            var field = col.descField || col.field;
            titleObj[field] = col.title;
        });
        var datePrefix = new Date().toISOString().split('T')[0];
        var fileName = `${reportText}_${datePrefix}_${Date.now()}.xlsx`;
        if (window.PHA_EXPORT?.XLSX) {
            PHA_EXPORT.XLSX(titleObj, data.rows, fileName);
        } else {
            alert('导出组件未加载,请检查依赖');
        }
	    })
	    .catch(error => {
	        PHA.Loading('Hide');
	        console.error('导出失败:', error);
	        alert(`导出失败: ${error.message}`);
	    });
}


window.PHA_EXPORT = window.PHA_EXPORT || {};
PHA_EXPORT.XLSX = function(titleObj, rowsData, fileName, colsFormatter) {
    const cols = Object.keys(titleObj).map(field => ({
        field: field,
        title: titleObj[field]
    }));
    const ws = XLSX.utils.json_to_sheet(rowsData, {
        header: Object.keys(titleObj), // 表头字段名
        skipHeader: false // 生成 Excel 表头行
    });
    const range = XLSX.utils.decode_range(ws['!ref']); 
    for (let colIdx = 0; colIdx <= range.e.c; colIdx++) {
        const cellAddr = XLSX.utils.encode_cell({ r: 0, c: colIdx });
        ws[cellAddr].s = { 
            font: { 
                name: '微软雅黑', 
                bold: true
            } 
        };
    }
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
    XLSX.writeFile(wb, fileName);
};
function GetCondition(){
	var formDataArr = PHA.DomData("#div-conditions", {
		doType: 'query',
		retType: 'Json'
	});
	return formDataArr.length > 0 ? formDataArr[0] : null;
}
function ClearCondition(){
	PHA.DomData("#div-conditions", {
		doType: 'clear'
	});
	$('#report').keywords('clearAllSelected');
}

3、页面右侧报表区域模版编写

<!-- 验证session过期 -->
<csp:method name=OnPreHTTP arguments="" returntype=%Boolean>
    d ##Class(websys.SessionEvents).SessionExpired() q $$$OK
</csp:method>

<style>
    .pha-no-data-blue {
        height: 100%;
        width: 100%;
        background: url(../images/no_data.png) no-repeat center;
    } 
    .pha-no-data-lite {
        height: 100%;
        width: 100%;
        background: url(../images/no_data_lite.png) no-repeat center;
    }   
</style>
<script language="cache" runat="server">
    s iconClsName = ""
    Set HISUIStyleCode = ##class(websys.StandardTypeItem).GetIdFromCodeOrDescription("websys","HISUIDefVersion")
    If (HISUIStyleCode = "") {
        s HISUIStyleCode = "blue"
        s iconClsName = "icon-paper-info"
    }
    s tabClassName = "pha-no-data-"_HISUIStyleCode
</script>
<div id="pha-stat-reptab" class="hisui-tabs tabs-gray #(tabClassName)#" data-options="fit:true,isBrandTabs:true">
    <div title="报表" iconCls="#(iconClsName)#"></div>
</div>

4、前台界面从后台传输数据action请求中转csp,其他页面也可使用此方法

<csp:method name=OnPreHTTP arguments="" returntype=%Boolean>
  i ##Class(websys.SessionEvents).SessionExpired() q 1
  q 1
</csp:method>
<script language="cache" runat="server">
 s action = $Get(%request.Data("action",1))
 s QUERY = $Get(%request.Data("QUERY",1))
 
 i QUERY="NTSCMJZCFJL" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCMJZCFJL(startdate,enddate)
 i QUERY="NTSCZYHZXX" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCZYHZXX(startdate,enddate)
 i QUERY="NTSCZYZDXX" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCZYZDXX(startdate,enddate)
 i QUERY="NTSCZYYZXX" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCZYYZXX(startdate,enddate)
 i QUERY="NTSCKJYWXHQK" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCKJYWXHQK(startdate,enddate)
 i QUERY="NTSCJYJG" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCJYJG(startdate,enddate)
 i QUERY="NTSCWSWJYJG" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCWSWJYJG(startdate,enddate)
 i QUERY="NTSCJCJG" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCJCJG(startdate,enddate)
 i QUERY="NTSCSSJL" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCSSJL(startdate,enddate)
 i QUERY="NTSCSMTZJL" d
 .s startdate=$Get(%request.Data("startDate",1))
 .s enddate=$Get(%request.Data("endDate",1))
 .w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCSMTZJL(startdate,enddate)
</script>

5、前台请求数据后,后台返回的数据格式,同时也是将query转换为json输出到前台。

/// 抗菌药物检测网统计报表
Class NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat Extends %RegisteredObject
{

/// // w ##class(NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat).NTSCMJZCFJL("2023-04-02","2024-04-02")
ClassMethod NTSCMJZCFJL(startdate As %String, enddate As %String) As %String
{
	
    Set cols = ##class(%DynamicArray).%New()
    Do cols.%Push(##class(%DynamicObject).%New())
    Do cols.%Get(0).%Set("field", "no")
    Do cols.%Get(0).%Set("title", "序号") 
    Do cols.%Push(##class(%DynamicObject).%New())
    Do cols.%Get(1).%Set("field", "type")
    Do cols.%Get(1).%Set("title", "类型")
    Do cols.%Push(##class(%DynamicObject).%New())
    Do cols.%Get(2).%Set("field", "admno")
    Do cols.%Get(2).%Set("title", "就诊编码")
    Set rows = ##class(%DynamicArray).%New()
    Set rs = ##class(%ResultSet).%New("NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat:NTSCMJZCFJLdata")
    Do rs.Execute(startdate, enddate)
    While rs.Next() {
        Set row = ##class(%DynamicObject).%New()
        Do row.%Set("no", rs.Get("no"))
        Do row.%Set("type", rs.Get("type"))
        Do row.%Set("admno", rs.Get("admno"))
        Do rows.%Push(row)
    }
    Do rs.Close()
    Set result = ##class(%DynamicObject).%New()
    Do result.%Set("cols", cols)
    Do result.%Set("rows", rows)
    Return result.%ToJSON()
}

/// Description:: 取住院科室
/// Output:      id:科室ID,locDesc:科室描述                   
/// Others:  d ##class(%ResultSet).RunQuery("NTSC.ExterIntface.AntiAgentStat.NTSCAntiAgentStat","NTSCMJZCFJLdata","2023-04-02","2024-04-02")    
Query NTSCMJZCFJLdata(startdate = "", enddate = "") As %Query(ROWSPEC = "no,type,admno") [ SqlProc ]
{
}

ClassMethod NTSCMJZCFJLdataExecute(ByRef qHandle As %Binary, startdate = "", enddate = "") As %Status
{
    Set repid=$I(^CacheTemp)
    Set qHandle=$lb(0,repid,0)
    Set ind=1
    s (paadm,no,type,admno )= "" 
    f  s paadm = $O(^PAADM(paadm)) q:paadm=""  d
    .s:paadm'="" no = $P($G(^PAADM(paadm)),"^",2)
    .s:paadm'="" type = $P($G(^PAADM(paadm)),"^",7)
    .s:paadm'="" admno = $P($G(^PAADM(paadm)),"^",81)
    .d outputRow8
    Quit $$$OK
outputRow8
 s row=$listbuild(no,type,admno)
 s ^CacheTemp(repid,ind)=row
 s ind=ind+1
 q
}

ClassMethod NTSCMJZCFJLdataClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = NTSCMJZCFJLdataExecute ]
{
    
    Set repid=$LIST(qHandle,2)
    Kill ^CacheTemp(repid)
    Quit $$$OK
}

ClassMethod NTSCMJZCFJLdataFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = NTSCMJZCFJLdataExecute ]
{
    
    Set AtEnd=$LIST(qHandle,1)
    Set repid=$LIST(qHandle,2)
    Set ind=$LIST(qHandle,3)
    Set ind=$o(^CacheTemp(repid,ind))
    If ind="" {             
        Set AtEnd=1
        Set Row=""
    }
    Else      {             
        Set Row=^CacheTemp(repid,ind)
    }
    s qHandle=$lb(AtEnd,repid,ind)
    Quit $$$OK

}