#
摘要: NET系統集成有自己獨立的登錄驗證方式。比如,跟報表集成時,不需要再使用報表內置的登錄界面,只需要將報表默認的參數用戶名fr_username和密碼fr_password發送給報表系統,觸發一下報表驗證方式就可以實現單點登錄了,以下用FineReport的.NET跨域單點登錄案例簡單介紹一下。
系統本身有獨立的登錄驗證方式如下圖:
1.觸發報表驗證方法
報表集成時不需要再一次...
閱讀全文
對于報表開發,很多情況下,自帶的函數就能滿足大部分用戶的報表制作需求,FineReport也不例外。但是在一些特殊領域,可能需要一些特殊的函數,在這種情況下,FineReport提供了自定義函數機制,可以由用戶根據業務需要自己來定義一些函數,但這些函數必須滿足函數定義規則。
先來了解一下FineReport的函數定義規則:Functionname(Para,Para,...),其中Functionname為函數名,Para為參數。
每一個函數都被定義成一個類,這個類必須要實現Function這個接口,在運算的時候首先通過函數名反射取得這個類,然后調用它的run(Object[] agrs)方法。下面以SUM這個函數為例。
SUM函數原理
由程序可以看到,SUM類用來運算SUM函數,他繼承了AbstractFunction類,而AbstractFunction實現了Function這個接口。
當函數運算的時候,先根據函數名取得運算該函數的類,如SUM(2,4,true)這個函數先根據函數名取得SUM這個類,然后調用SUM類的run(Object[] args)方法,args中存放的是SUM函數的參數,運算的時候可以從args中取得參數進行運算。如執行結果為SUM(2,4,true)=2+4+1=7。
SUM函數所使用代碼:
package com.fr.report.script;
import java.lang.reflect.Array;
import com.fr.report.script.core.FArray;
import com.fr.report.script.core.FunctionHelper;

public class SUM extends AbstractFunction
{

public Object run(Object[] args)
{
double result = 0;

for (int i = 0; i < args.length; i++)
{

if (args[i] == null)
{
continue;
}
result += parseObject(args[i]);
}
return FunctionHelper.parsePrimitiveDouble(result);
}

private double parseObject(Object obj)
{

if (obj instanceof Number)
{
return ((Number) obj).doubleValue();

} else if (obj instanceof Boolean)
{
return ((Boolean) obj).booleanValue() ? 1 : 0;

} else if (obj instanceof FArray)
{
FArray array = (FArray) obj;
double sum = 0;

for (int i = 0; i < array.length(); i++)
{
sum += parseObject(array.elementAt(i));
}
return sum;

} else if (obj != null)
{

try
{
return Double.parseDouble(obj.toString());

} catch (NumberFormatException exp)
{
return 0;
}
}
return 0;
}
}

實現步驟
編寫自定義函數
下面以一個簡單的自定義函數例子來說明使用自定義函數。我們定義一個函數StringCat,他的作用是把所有的參數以字符串的形式連接起來。
StringCat函數使用規則為StringCat(Para,Para,Para…….);
其中Para為該函數的參數,個數不限。
由概述可知AbstractFunction實現了Function這個接口,因此StringCat可以直接繼承AbstractFunction類,完整代碼如下:
package com.fr.function;

import com.fr.script.AbstractFunction;


public class StringCat extends AbstractFunction
{

public Object run(Object[] args)
{
String result = "";
Object para;

for (int i = 0; i < args.length; i++)
{
para = args[i];
result += para.toString();
}
return result;
}
}

這里要注意,使用函數StringCat(Para,Para,Para…..)時,根據函數名取得運算該函數的類StringCat,并將參數傳入類中的args對象數組中,執行該類的run函數。
而在run函數中即實現了將傳入的參數以字符串的形式連接起來。并返回最終形成的字符串。
編譯自定義函數
將編譯后的StringCat.class放到FineReport的安裝目錄WEB-INF下面的classes目錄下,因為StringCat.java屬于包com.fr.function,所以StringCat.class需要放到classes\com\fr\function目錄下。
注冊自定義函數
生成該函數的類后需要在設計器中進行注冊,才可以使用該函數。打開服務器|函數管理器,選擇剛剛定義好了StringCat類,如下圖
函數名稱可以自定義,如這邊定義為StringCat;
同時可以添加該函數的使用說明,如上圖所示的描述
使用自定義函數
注冊好自定義函數后,制作報表時便可直接使用了,使用方法與內置的函數是相同的。
新建報表,定義兩個報表參數para1、para2,類型分別為字符串型與整形,默認值分別為空字符串與0
在空白報表的任意單元格里寫入公式:=StringCat($para1,$para2)(注意:寫入公式的時候在參數名前加$,表明這是使用的參數)
點擊分頁預覽在參數控件中,寫入參數值如para1為:FineReport,para2為:123。
點擊查詢可以看到結果

說明StringCat公式可以正常使用啦。
對于一款軟件或產品,尤其是一些企業級應用的IT軟件,是不可能滿足所有需求的。尤其是針對業務化的產品需求,某些個性化的需求就要進行二次開發。二次開發需要API接口,無論是什么樣的開發,開發人員都需要對開發的產品大內部結構有所了解。在應用廣泛的企業報表領域,開發在所難免,下圖展示了我在工作中開發的FineReport的內核示意圖。

這款類似于Excel的報表軟件,成為設計器。在設計器中新建一個工作薄就是建了一個WorkBook,WorkBook相當于一個容器,里面可以放任意個WorkSheet,就相當于在設計器的一個工作薄中新建了多個sheet。每個WorkSheet是由任意個單元格CellElement組成,因此CellElement是一個模板的最小元素。獲得WorkBook后,必須取得其中的某個WorkSheet才能對這個報表中的CellElement進行操作,這對于模板還是結果都是一樣的,如果以模板為例,最基本的內核結構就是如下面這張圖
由于每個部分各自包含了很多屬性,比如可以設置單元格的前景、背景、邊框、字體、字號等;又比如每個WorkSheet中可以添加,刪除單元格、可以設置每個sheet的頁面屬性、可以給每個sheet中添加圖表懸浮元素等;再比如可以對WorkBook進行執行獲得結果并導出成各種格式、可以進行打印、添加工具欄等等。
正是基于這樣,再開發時會有豐富的API接口可供調用。以下是FineReport包含的所有開放的API。
由圖可有看出,對于這樣的開發可以從以下幾個功能點進行開發。
報表數據源
設計器本身已經提供了數據庫數據源、文本數據源、xml數據源等多種數據來源方式,同時還可以通過java程序自行生成數據來源,只需要實現TableData接口便可以了。
輸入輸出報表
在程序中新建一個報表對象同時也可以直接讀取一個cpt模板來生成,經過處理的報表最終可以導出成多種形式,可以保存為程序網絡報表在web端直接訪問,也可以導出為excel、pdf、word、cpt等多種格式文件。
設置單元格屬性及報表屬性編輯
可以對報表對象的單元格屬性、web屬性、參數、頁面設置等多個屬性進行控制,可以自由控制單元格的顯示樣式、工具欄的按鈕、參數面板的展示、參數的賦值等等。
自定義填報
開放的填報api接口能夠根據自己的需要來定義填報入庫方式,通過填報接口,可以往數據庫中保存用戶操作日志、在填報成功與失敗時進行各種處理等等。
開發的工作雖枯燥也有意思,閑來無事時也會開發一些有趣的應用,比如下圖把天氣集成到報表頁面。

關于這個問題,制作數據地圖的方法已不新奇,總體來說有這么幾類方案:
一類方案:直接在excel里制作
優勢:個人小數據量應用較為方便簡單
缺點:需要熟悉VBA,且更強大的功能對VBA水平要求較高
1、繪制地圖圖形 + VBA宏語言
思路:用插入圖形"任意多邊形"繪制地圖;每一個"任意多邊形"賦予正確名稱;對"任意多邊形"賦值;利用VBA對"任意多邊形"的值進行操作, 例如上色。
先準備一張所需要的地圖圖片,網上都有,可以下載
然后利用插入繪制多邊形圖片將地圖中的區域描邊

選定好的區域可以在左上角修改名稱

將數據表中的數據和地圖中的地區做關聯,這里就要用到VBA了。
代碼:
Sub ProvRefill()
ActiveSheet.Shapes.Range(Array("shandong")).Select
With Selection.ShapeRange.Fill
.Visible = msoTrue
.ForeColor.ObjectThemeColor = msoThemeColorAccent1
.ForeColor.TintAndShade = 0
.ForeColor.Brightness = -0.5
.Transparency = 0
.Solid
End With
End Sub
這段代碼是修改地圖所選區域的顏色的,其他功能類似,懂VBA的會覺得簡單,不懂的可以自行百度。
2、EXCEL插件集成
這類插件有很多,推薦Power Map for Excel 2013,安裝好之后,選擇數據區域,啟動就行


二類方案:其他軟件
優勢:地圖已集成在內,可連接數據庫,已有功能強大大數據量處理具有優勢
缺點:自定義開發對人員水平要求較高,較困難
這一類軟件一般是數據可視化的軟件,能用到EXCEL數據源的,現在比較普遍的是報表工具和所謂商業智能大數據工具。
不多說,大家可能覺得陌生,那就直接上實例。
這里介紹FineReport(功能強大最實際的報表工具)
展示數據地圖不在話下,關鍵有地圖鉆取功能。
所謂鉆取就是:比如你點擊山東省,進入山東省省地圖,顯示山東省各市的數據,數據的展示方式可以使用其他圖表,比如條形圖、氣泡圖等等。


詳細步驟:
1、 準備數據源
將excel的數據導入到這個報表設計器里,如果你的excel數據是取自于數據庫的話,可以直接從設計器里讀取數據庫的數據。
2、 合并一片單元格,點擊菜單欄中的插入>單元格元素>插入圖表,選擇地圖,然后點擊確定,如下圖:(這里申明一下,這個軟件類似于EXCEL,所以一些操作術語何以類比于EXCEL)

1、 選擇地圖類型,國家地圖、省級地圖還是其他云云,或者你有自定義的SVG地圖也行。這里注意,地圖的區域名要和區域數據字段的名字對應。

個人覺得鉆取才是其亮點,所以這里一定要介紹一下。
鉆取:
定義好地圖的類型之后,就可以為地圖定義數據來源了,選中地圖,點擊圖表屬性表-數據,進入數據設置面板,地圖展現方式選擇多層鉆取,如下圖:

從上圖可以看到,鉆取層級下有個中國的文件夾,雙擊即可打開查看中國下面的省份,選中中國文件夾,右擊,則會跳出層級設置對話框,如下圖:

要實現點擊山東省能出現一張柱狀圖,這個其實是兩張圖表關聯的,所謂“聯動”。
聯動:
合并一片單元格,點擊插入>單元格元素>插入圖表,選擇柱形圖,點擊確定即可添加一張柱形圖。
柱形圖的數據來源:(這里我都是直接用數據庫的數據源)

在此,地圖和柱形圖都已經設置好了,如果要實現聯動,需要在設置交互屬性。
選中地圖,在圖表屬性表中選擇特效,點擊交互屬性,添加一個超級鏈接,即點擊,添加一個圖表超鏈-聯動單元格,設置如下圖:

到這里基本就完成了,感覺自己做得圖有些low,別毀了人家名聲,其實人家功能很強大,可視化很炫的。
另附幾張圖:



其他軟件的話,還有商業智能可視化類的tableau, FineBI,可能對大家比較陌生,就不做教程介紹了。
總之,利用excel中的數據源制作地圖圖表方法多多,不當之處還請指正。
很多人會遇到這種情況,在瀏覽頁面時,發現鼠標右鍵不啟用了。咦?刷新刷新再刷新,并無卵用,然后怒敲鼠標(沒錯,我就是這么暴力),更換瀏覽器,無用,最后棄之。其實,這是因為設計人員對頁面啟用了“禁用右鍵”功能,目的是為了防止內容被抄。
曾經也是受害者的我,如今作為一名小小的IT開發人員,就來告訴你如何“禁用右鍵”!
這里列舉一個我在利用FineReport開發報表時遇到的案例。
啟用“禁止右鍵”
報表大家都懂吧,啟用“禁用右鍵”功能,往往是出于展示過程中的數據安全和操作上的失誤考慮(想想銀行動輒幾千幾百萬的金額,分分鐘要長個心眼啊)。
首先在頁面中調用模板,一般是將url放在iframe中,然后通過點擊相應的樹節點查看報表,一般報表都會設置權限,如果設置權限,登錄系統后可能有些用戶通過點擊右鍵中的屬性查看url然后訪問,這樣對系統來說其實是很不安全的,因此禁止用戶通過右鍵查看url,此時可以使用禁用菜單右鍵功能。
2. 實現步驟
點擊模板>模板web屬性>(填報,數據分析,分頁預覽設置),選擇為該模板單獨設置,在下面的事件設置里面添加一個加載結束事件,完整js代碼如下:
1.//點擊右鍵 無動作
document.oncontextmenu=new Function("return false");
2.//點擊右鍵 彈出提示

document.oncontextmenu=function(e)
{
alert("提示內容");
return false;
}
這段代碼的基本原理是讓用戶的頁面右鍵點擊事件返回false,禁止彈出菜單。
如果模板中有參數面板,希望一調用模板就禁用右鍵,而不是查詢之后禁用,則需要在參數面板的查詢按鈕中添加初始化事件,寫入上述js代碼。


查詢之前就做提示和禁用
破解“禁用右鍵”
找到瀏覽器頂部菜單中的【工具】按鈕,在下拉菜單中,選擇【Internet選項】
打開Internet選項后,再切換到【安全】選項卡,然后再點擊底部的【自定義級別】
然后在打開的【安全設置-Internet區域】對話框中,找到【活動腳本】設置選項,然后將默認的“啟用”更改為【禁用】,最后再一路點擊底部的【確定】。

然后關閉再重啟瀏覽器,再打開剛剛的網頁,你就會發現“殘疾”的鼠標右鍵能正常點擊了。
以上就是我的方法,不足之處還請多多指點。
摘要: 今天我們來聊聊Java防盜鏈,多說無用,直接上應用案例。
這里所用的工具是報表軟件FineReport,搭配有決策系統(一個web前端展示系統,主要用于權限控制),可以采用java防盜鏈的方式來實現頁面權限。
瀏覽器中直接輸入報表URL的時候,它的頭文件是空的,因此,可以在訪問的時候做兩個判斷:頭文件是否為空以及以什么頁面進行跳轉,如果不符合跳到錯誤頁面即可。
什么是Referer?
這里...
閱讀全文
1. 環境搭建
1.1 環境準備
首先確認HANA Studio的環境是否允許工程進行NewFile的操作,不行的話要考慮更新Studio的版本。

HANAStudio需要依賴Java jdk1.6或者1.7的版本

1.2 操作步驟
需要獲取到SYSTEM賬號的權限,在SYSTEM權限下進行操作
Adda System

填寫正確的主機名(如IP地址)和HANA的instance number(詢問管理員獲得)

填寫賬號名和密碼,點擊finish

Create repository
點擊Repositories頁簽,Create repository Workspace

新建一個Package或者選擇一個原有的Package
如下圖,右鍵->New->Repository Package 新建Package,再彈出的頁面輸入包名即可創建

New file XMLASrvDef.xsxmla
在新建的包下新建文件XMLASrvDef.xsxmla

編輯文件,輸入service{*},點擊激活按鈕,如下圖:

激活后的文件狀態發生改變

Newfile .xsapp
同理,新建文件.xsapp,不需要輸入內容,點擊激活按鈕
Newfile . xsprivileges
代碼:
{"privileges":
[{"name":"SYSTEM","description":"Administrationprivilege"}]
}
同理,新建文件. xsprivileges,編輯文件,輸入代碼如下:點擊激活按鈕
New file .xsaccess
同理,新建文件. xsaccess,編輯文件,輸入代碼如下:
{
"exposed" : true,
"authorization" :["test::SYSTEM"]
}
點擊激活按鈕
Newfile test.html
用于測試環境是否新建成功,同理編輯文件,點擊激活按鈕

配置必要的權限

Analytic Privileges中添加_SYS_BI_CP_ALL

Application Privileges中添加test::SYSTEM

1.3 測試連接
確保HANA 環境中至少存在一個Analytic view,假如沒有,需要自己新建用于測試
打開瀏覽器,輸入地址,測試連接

地址的格式:http://hostname:80[instance number]/test/XMLASrvDef.xsxmla
輸入用戶名和密碼結果返回404,說明服務器接到了請求,給出了響應
保險起見,可以輸入http://hostname:80[instance number]/test/test.html

如果看到上圖,說明服務已經開啟
2.新建XMLA數據連接
點擊服務器>定義數據連接,新建一個XMLA數據連接,數據庫類型選擇SAP HANA,填寫url與賬號密碼,選擇Catalog,測試連接,連接成功即可


3. FAQ
3.1
假如以上權限配置好后仍舊出現問題,嘗試配置如下權限Granted Roles中添加
sap.hana.uis.db::SITE_DESIGNER: to designapplication sites
sap.hana.uis.db::SITE_USER: to useapplication sites
sap.hana.xs.lm.roles::Administrator
sap.hana.xs.ide.roles::EditorDeveloper
Object privileges中添加
GRANT_ACTIVATED_ROLE
3.2 環境搭建中遇到的問題
1.Serverreturned HTTP response code: 403 for URL
可能是(1)用戶名密碼錯誤 (2)用戶權限沒有配置好 (3)新建的文件如privileges沒有激活,需要檢查
2.Serverreturned HTTP response code: Connection refused: connect
可能是設計器中填寫的url有問題,檢查ip地址,檢查端口號,檢查xsxmla文件所在的路徑是否輸入正確
3.新建的文件激活時遇到問題
請聯系SAP管理員
3.3 jdbc連接hana的注意點

圖中的SQL驗證查詢是必填的選項,這個sql的獲取,可以通過以下途徑
打開HANAStudio,隨便預覽一個數據源,點擊右上角的show log可以查看歷史查詢的SQL語句,把語句拿過來復制粘貼到此處即可
摘要: 文件輸出的多樣性,準確性和穩定性對于我們常用的報表軟件來說很重要。報表的輸入是指從報表的模板文件(XML格式的)創建WorkBook對象,輸出則指將報表保存為各種格式文件,比如Pdf、Excel、Word這種常見的文件格式,比如FineReport還支持cpt、Svg、Csv、Image(包含png、 jpg、gif、 bmp、wbmp)等多種文件格式。
...
閱讀全文
摘要: 數據庫保存的是陽歷日期,有時候會遇到把陽歷換成陰歷的需求,在報表開發過程中,可以首先定義一個可以將陽歷轉為陰歷的類,然后自定義FineReport函數,在run方法中獲取年月日參數并調用之前的類將陽歷轉為陰歷,最終返回給報表。
閱讀全文
摘要: 很多人在開發報表的時候會遇到將多張表樣相同的excel導入到模板,然后提交至數據庫中。但問題是很多情況,在線導入不支持一次性選擇多個excel,一次只能選擇一個excel,也不能將多個excel中的數據在不提交入庫的前提下導入到模板中,即如果在導入excel之前,web頁面里面有數據,導入excel之后會覆蓋之前的數據.這樣的問題可以利用FineReport自定義一個excel導入按鈕來解決
閱讀全文