身份證一類讀卡器讀取的照片信息,保存在Access數(shù)據(jù)庫中一般為OLE型字段,圖片為BMP格式,因為是用其讀卡器寫入的,其數(shù)據(jù)類型為常二進(jìn)制數(shù)據(jù)。
再用報表或EXCEL讀取這些圖片時,如果將該圖片字段拖入單元格后,預(yù)覽就看不到圖片了。EXCEL如何讀取這類圖片網(wǎng)上有教程,這里不多說。如果你要用報表軟件FineReport來展現(xiàn)這類圖片該如何做呢?
思路是采用FineReport的自定義函數(shù),使用java的jna調(diào)用本地的WltRS.dll,將數(shù)據(jù)庫OLE字段中的長二進(jìn)制數(shù)據(jù)轉(zhuǎn)為.wlt文件,再調(diào)用本地方法將.wlt文件轉(zhuǎn)為.bmp圖片,最終自定義函數(shù)返回圖片在FineReport中顯示。
1、前提準(zhǔn)備
本地庫文件WltRS.dll保存在E:\bmp\WltRS.dll(位置可變,但ixu保證以自定義函數(shù)中的路徑一致);eclipse項目中導(dǎo)入FINEREPORT的jar包。
2、實現(xiàn)自定義函數(shù)
自定義一個函數(shù)類BinaryImage.java,該類繼承AbstractFunction,在run()方法中使用java的jna調(diào)用本地庫文件WltRS.dll,最終返回圖片。代碼如下:
Java代碼package com.FineReport.function;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.FineReport.data.core.db.BinaryObject;
import com.FineReport.script.AbstractFunction;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class BinaryImage extends AbstractFunction{
//加載dll,"E:\\bmp\\WltRS"是dll的文件完整路徑,但不帶后綴名,生成WltRS.class
static WltRS wltrs = (WltRS) Native.loadLibrary("E:\\bmp\\WltRS", WltRS.class);
static int index = 0;
public Object run(Object[] args) {
int current = index;
//args[0] 是 BinaryObject對象,取為bo
BinaryObject bo = (BinaryObject)args[0];
//將bo轉(zhuǎn)換為.wlt文件,并保存在位置E:\bmp\;本地方法GetBmp的第一個參數(shù)是wlt文件的路徑
getFile(bo.getBytes(), "E:\\bmp\\", current + ".wlt");
//讀取.wlt為文件
File file = new File("E:\\bmp\\" + current + ".wlt");
//調(diào)用本地方法,在相同路徑下生產(chǎn).bmp
wltrs.GetBmp("E:\\bmp\\" + current + ".wlt", 1);
//讀取并返回圖片
File imagefile = new File("E:\\bmp\\" + current + ".bmp");
BufferedImage buffer = null;
try {
buffer = ImageIO.read(imagefile);
} catch (IOException e) {
e.printStackTrace();
}
index = (++index)%300;
return buffer;
}
// byte[]轉(zhuǎn)換為file的方法
public static void getFile(byte[] bfile, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if(!dir.exists() && dir.isDirectory()){//判斷文件目錄是否存在
dir.mkdirs();
}
file = new File(filePath+"\\"+fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
//用jna調(diào)用本地方法的必須步驟,具體含義不明
interface WltRS extends Library{
//定義要調(diào)用的本地方法
void GetBmp(String str, int i);
}
將編譯后的BinaryImage.class、WltRS.class根據(jù)包名拷貝至報表工程如報表安裝目錄下的WebReport\WEB-INF\classes\com\FineReport\function\文件夾下。
3、使用自定義函數(shù)
將OLE類型字段的值顯示為圖片。啟動設(shè)計器,點擊服務(wù)器>函數(shù)管理器,新增自定義函數(shù)BINARYIMAGE,選擇com.FineReport.function.BinaryImage類:

將身份證讀卡器寫入Access數(shù)據(jù)庫OLE型字段的照片信息拖入單元格,雙擊,在數(shù)據(jù)列>高級>自定義顯示中使用自定義函數(shù)轉(zhuǎn)換成圖片:
