如何在FTL(FreeMarker)中通过URL传递用户输入日期与列选择参数
实现方法
FreeMarker是服务端渲染模板,页面加载完成后,用户选单选框、填日期的操作都在浏览器端完成,没必要回传服务端重刷页面,加几行原生JS就能实现需求,具体改法如下:
- 给两个单选按钮加
value属性,分别对应两个报表的模板文件名,默认选中第一个单选框 - 不要把生成报告的a标签href写死,绑定点击事件,触发时实时获取用户填的日期、选中的报表类型
- 做基础的日期合法性校验后,拼接出完整的目标URL直接跳转即可
- 原代码里直接把
<option>塞在<div>下不符合HTML规范,示例里改成了普通div做列展示,如果需要支持用户自定义勾选列,再换成多选控件即可。
完整可运行代码
<!-- 日期输入框 --> <input type="date" id="quality-fromdate" required> <input type="date" id="quality-toDate" required> <!-- 单选按钮配置value,默认选中第一组 --> <input id="radiobutton1" type="radio" name="radio-button" value="production_1.rptdesign" checked> <div class="select-columns-options-1" id="select-columns-options1"> <div>Product Name</div> <div>Order Id</div> <div>Quantity Ordered</div> <div>Quantity To Produce</div> <div>Due Date</div> <div>Estimated Completion Time</div> </div> <input id="radiobutton2" type="radio" name="radio-button" value="production_2.rptdesign"> <div class="select-columns-options-2"> <div>Product Name</div> <div>Quantity Ordered</div> <div>Quantity To Produce</div> </div> <!-- 生成按钮不写死href --> <a href="javascript:void(0)" id="generateReportBtn">Generate Report</a> <script> document.getElementById('generateReportBtn').addEventListener('click', () => { // 读取用户输入 const dateFrom = document.getElementById('quality-fromdate').value; const dateTo = document.getElementById('quality-toDate').value; const selectedReport = document.querySelector('input[name="radio-button"]:checked')?.value; // 基础校验 if (!dateFrom || !dateTo || !selectedReport) { alert('请完善起止日期和报表类型选择'); return; } if (new Date(dateFrom) > new Date(dateTo)) { alert('起始日期不能晚于结束日期'); return; } // 拼接跳转URL,硬编码的基础地址可以换成FTL变量适配不同部署环境 const target = new URL('http://localhost:9191/preview'); target.searchParams.set('__report', selectedReport); target.searchParams.set('__format', 'pdf'); target.searchParams.set('DateFrom', dateFrom); target.searchParams.set('DateTo', dateTo); window.location.href = target.toString(); }); </script>
补充说明
- 如果报表服务的域名、前缀需要根据部署环境切换,直接把代码里硬编码的
http://localhost:9191/preview换成FTL变量即可,比如后端渲染时传入reportBasePath变量,这里写${reportBasePath}就行,不用改其他逻辑。 - 如果你一定要用纯FTL实现(每次修改选项都提交表单刷新页面),可以把所有输入项放在form表单里提交到当前路由,后端拿到日期、报表类型参数传回FTL,用
<#if>判断输出不同的href,参考代码如下:
<form method="get"> <input type="date" name="dateFrom" value="${(dateFrom!'')}"> <input type="date" name="dateTo" value="${(dateTo!'')}"> <label><input type="radio" name="reportType" value="1" <#if (reportType!'1') == '1'>checked</#if>> 第一组列</label> <label><input type="radio" name="reportType" value="2" <#if (reportType!'1') == '2'>checked</#if>> 第二组列</label> <button type="submit">确认参数</button> </form> <#if reportType!'1' == '1'> <a href="http://localhost:9191/preview?__report=production_1.rptdesign&__format=pdf&DateFrom=${dateFrom!''}&DateTo=${dateTo!''}">生成报告</a> <#else> <a href="http://localhost:9191/preview?__report=production_2.rptdesign&__format=pdf&DateFrom=${dateFrom!''}&DateTo=${dateTo!''}">生成报告</a> </#if>
这种方案需要额外写后端接收参数的逻辑,每次改参数都要刷新页面,体验很差,非特殊场景不推荐使用。
内容的提问来源于stack exchange,提问作者maahi_m
相关产品推荐
相关产品推荐

