首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

FineReport 自定義控件開發全流程:從註冊到前後端實現的完整指南

     編輯:Java 綜合教學

FineReport 自定義控件開發全流程

FineReport 作為插件化架構的報表工具,提供了豐富的擴展點。當內置控件無法滿足特定業務需求(如特殊過濾邏輯、自定義交互)時,開發自定義控件是最佳選擇。本文以「自定義下拉框」為例,完整演示從後端註冊、核心邏輯實現到前端渲染的全鏈路開發過程。

架構圖解:控件運行機制

後端 (Java)                          前端 (JavaScript)
┌─────────────────────┐               ┌─────────────────────┐
│ WidgetRegister      │  1.註冊信息   │                     │
│ - classForWidget()  │◄─────────────►│                     │
│ - appearanceForWidget()                │                     │
│ - iconPathForWidget()                  │                     │
│ - nameForWidget()                      │                     │
└─────────┬───────────┘               └──────────┬──────────┘
          │                                      │
          ▼                                      ▼
┌─────────────────────┐               ┌─────────────────────┐
│ CustomComboBox      │  2.數據模型   │ FR.CustomComboBoxEditor │
│ - getXType()        │◄─────────────►│ - _init()           │
│ - createDataFilter()│               │ - shortcut映射      │
└─────────┬───────────┘               └─────────────────────┘
          │
          ▼
┌─────────────────────┐
│ CustomComboBoxDataFilter │
│ - isMatch() 核心過濾邏輯 │
└─────────────────────┘

第一步:實現控件註冊接口

package com.hg.free.plugin.customcombo.param;

import com.fr.design.designer.creator.XComboBox;
import com.fr.design.fun.impl.AbstractParameterWidgetOptionProvider;
import com.fr.form.ui.Widget;

public class WidgetRegister extends AbstractParameterWidgetOptionProvider {

    @Override
    public Class<? extends Widget> classForWidget() {
        // 返回核心控件類 (後端數據模型)
        return CustomComboBox.class;
    }

    @Override
    public Class<?> appearanceForWidget() {
        // 返回設計器界面編輯器類 (設計時UI)
        return XComboBox.class;
    }

    @Override
    public String iconPathForWidget() {
        // 設計器面板顯示的圖標路徑 (相對 classpath)
        return "/com/fr/web/images/combobox.png";
    }

    @Override
    public String nameForWidget() {
        // 設計器面板顯示的控件名稱
        return "自定義下拉框";
    }
}

第二步:實現核心控件類 (後端數據模型)

package com.hg.free.plugin.customcombo.param;

import com.fr.form.ui.ComboBox;
import com.fr.ui.DataFilter;

public class CustomComboBox extends ComboBox {
    private static final long serialVersionUID = 7169771062153345236L;

    @Override
    public String getXType() {
        // 關鍵:前端通過此類型標識查找對應的 JS 渲染器
        return "customcombo";
    }

    @Override
    protected DataFilter createDataFilter() {
        // 核心:返回自定義過濾器,改變匹配邏輯
        return new CustomComboBoxDataFilter();
    }
}

第三步:實現自定義數據過濾器 (核心業務邏輯)

package com.hg.free.plugin.customcombo.param;

import com.fr.form.ui.ComboBoxDataFilter;

public class CustomComboBoxDataFilter extends ComboBoxDataFilter {
    
    @Override
    public boolean isMatch(String txt, String filter) {
        // 原始邏輯:前綴匹配 (txt.startsWith(filter))
        // 自定義邏輯:包含匹配 (txt.contains(filter))
        
        if (txt == null && filter != null) return false;
        if (txt == null && filter == null) return true;
        
        // 支持大小寫不敏感包含匹配
        return txt.toLowerCase().contains(filter.toLowerCase());
    }
}

業務場景對比

場景原始匹配自定義匹配
用戶輸入「京」匹配「北京」、「京津」
不匹配「南京」
匹配「北京」、「南京」、「京津」
用戶輸入「sh」匹配「Shanghai」
不匹配「shanghai」
匹配「Shanghai」、「shanghai」、「Sh」

第四步:前端 JS 渲染器實現

;(function($) {
    // 繼承內置 ComboBoxEditor
    FR.CustomComboBoxEditor = FR.extend(FR.ComboBoxEditor, {
        _init: function() {
            // 調用父類初始化
            FR.CustomComboBoxEditor.superclass._init.apply(this, arguments);
            
            // 可在此擴展前端行為:
            // - 自定義下拉面板模板
            // - 添加鍵盤快捷鍵
            // - 集成第三方 UI 庫 (如 Select2)
        }
    });
    
    // 關鍵:將 xtype "customcombo" 映射到渲染器
    $.shortcut("customcombo", FR.CustomComboBoxEditor);
})(jQuery);

前後端交互原理

  1. 後端生成配置 JSON,包含 xtype: "customcombo"
  2. 前端解析配置,調用 $.shortcut("customcombo") 獲取構造函數
  3. 實例化 FR.CustomComboBoxEditor,傳入配置數據
  4. 渲染器生成 DOM,綁定事件,完成交互

打包部署:Ant 構建腳本

<project name="custom-combo-plugin" default="jar">
    <property name="src.dir" value="src"/>
    <property name="build.dir" value="build"/>
    <property name="dist.dir" value="dist"/>
    
    <target name="compile">
        <javac srcdir="${src.dir}" destdir="${build.dir}" 
               includeantruntime="false" encoding="UTF-8">
            <classpath>
                <fileset dir="${fr.home}/WebReport/WEB-INF/lib" includes="*.jar"/>
            </classpath>
        </javac>
    </target>
    
    <target name="jar" depends="compile">
        <jar destfile="${dist.dir}/custom-combo.jar" basedir="${build.dir}">
            <manifest>
                <attribute name="Plugin-Class" value="com.hg.free.plugin.customcombo.param.WidgetRegister"/>
            </manifest>
        </jar>
    </target>
</project>

安裝驗證步驟

  1. 將生成的 custom-combo.jar 放入 WebReport/WEB-INF/lib
  2. 重啟 FineReport 應用服務器
  3. 進入設計器,組件面板出現「自定義下拉框」圖標
  4. 拖拽到報表/表單,配置數據集
  5. 預覽測試:輸入關鍵字驗證模糊匹配效果

擴展方向:更多自定義能力

🎨 UI 深度定制

  • 重寫前端 _init 替換下拉模板
  • 集成 Select2、Chosen 等豐富 UI 庫
  • 添加分組標題、圖標、多選標籤

🔌 數據源擴展

  • 實現 WidgetDataProvider 接口
  • 支持 REST API、樹形數據、懶加載
  • 緩存策略優化大數據量下拉

✅ 校驗與聯動

  • 實現 Validator 接口自定義校驗規則
  • 監聽值變化觸發其他控件聯動刷新
  • 集成表單引擎驗證框架

🌐 國際化支持

  • 資源文件配置多語言提示信息
  • 前端根據 locale 動態加載語言包
  • 日期/數字格式本地化

開發調試技巧

  • 熱部署:配置 IDE 熱替換類文件,無需重啟驗證 Java 邏輯
  • 前端調試:瀏覽器 F12 斷點調試 JS,Console 查看 xtype 映射
  • 日誌追蹤:log4j.logger.com.fr=DEBUG 觀察控件生命周期
  • 源碼參考:FineReport 源碼中 ComboBox、ComboBoxDataFilter 是最佳學習範本

掌握 FineReport 自定義控件開發,關鍵在於理解 後端數據模型 ↔ xtype 標識 ↔ 前端渲染器 的三角映射關係。以此為核心,配合插件化打包部署,即可將任意業務邏輯封裝為可視化組件,極大提升報表開發效率與表達能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved