本文通過一個實例概要講解如何在asp.net程序中配合sql server2000進行word文件的存儲和調用過程(沒有使用vba )。
(1) 建立數據庫
首先,我們在數據庫中建立一個表,表中有三個字段,filename(varchar,50),posttime(datetime,8), filecontent(image,16),分別存儲文件名稱,上傳時間和word文件的具體內容,其中filename為主鍵。具體的sql腳本如下:
create table [dbo].[word] (
[filename] [varchar] (50) collate chinese_prc_ci_as not null ,
[posttime] [datetime] not null ,
[filecontent] [image] not null
) on [primary] textimage_on [primary]
(2) 上傳并存儲word文件
在vs.net中建立一個asp.net web應用程序,在界面內加入如下控件
控件類型 | id | text | 說明 |
label | label1 | 請輸入文檔的標題 | |
label | label2 | 請選擇具體文檔 | |
file field | file1 | 上傳控件(要將此html控件轉化為服務器控件) | |
textbox | name_textbox | 用于錄入文檔標題 | |
button | btn_ok | 上傳文件 | |
button | btn_get | 讀取文件 | |
hyperlink | hyperlink1 | 打開 | 用于打開word文檔 |
上傳文件時首先通過上傳控件找到所需上傳的文件,然后獲取文件的大小,最后以流的形式寫入數據庫,具體代碼為:
private void btn_ok_click(object sender, system.eventargs e)
{
string name=name_textbox.text;
//接收上傳文件
stream filestream=file1.postedfile.inputstream;
//獲取上傳文件字節的大小
int length=file1.postedfile.contentlength;
byte[] worddata=new byte[length];
//從流中讀取字節并寫入worddata
int n=filestream.read(worddata,0,length);
//獲取當前時間
datetime time=datetime.now;
//連接數據庫
sqlconnection conn=new sqlconnection();
conn.connectionstring="workstation id=tianchunzhu;packet size=4096;integrated security=sspi;data source=tianchunzhu;persist security info=false;initial catalog=test";
sqlcommand cmd=new sqlcommand();
cmd.connection=conn;
cmd.commandtext="insert into word (filename,posttime,filecontent) values (@filename,@posttime,@filecontent)";
sqlparameter nameparam=new sqlparameter("@filename",system.data.sqldbtype.varchar,50);
nameparam.value=name;
cmd.parameters.add(nameparam);
sqlparameter timeparam=new sqlparameter("@posttime",system.data.sqldbtype.datetime,8);
timeparam.value=time;
cmd.parameters.add(timeparam);
//添加word文件
sqlparameter contentparam=new sqlparameter("@filecontent",system.data.sqldbtype.image); ①//見本段最后注解
contentparam.value=worddata;
cmd.parameters.add(contentparam);
conn.open();
cmd.executenonquery();
conn.close();
}
注①:此處由于是image類型文件,事先可能無法預測文件的大小,因此可不必指定size參數。如果希望控制上傳文件的大小則可以輸入size參數。如指定1000,則上傳時最大可以上傳1k的word文檔。
(3) 從數據庫中讀取數據并恢復為word文件
讀取數據時先將數據從數據庫中讀入緩沖區,然后再從緩沖區寫入最終文件。因此首先要開辟一個緩沖區并設定它的大小,每當緩沖區讀滿時就要將緩沖區內的數據寫入文件,以清空緩沖區并繼續向緩沖區讀數據,直到最后一次將緩沖區內剩余的數據全部寫入文件,新的word文檔即可生成。
由于這一部分用到了字節流的輸入輸出操作,因此要引用system.io命名空間
下面是關于這一部分的完整代碼:
private void btn_get_click(object sender, system.eventargs e)
{
//連接數據庫
sqlconnection conn=new sqlconnection();
conn.connectionstring="workstation id=tianchunzhu;packet size=4096;integrated security=sspi;data source=tianchunzhu;persist security info=false;initial catalog=test";
sqlcommand cmd=new sqlcommand();
cmd.connection=conn;
//根據textbox中指定的文件名進行查找讀取
cmd.commandtext="select filecontent from word where filename='"+name_textbox.text.tostring()+"'";
filestream fs;
binarywriter bw;
//設定允許讀取到緩沖區的最大長度
int buffersize=100;
//要將字節流讀入的緩沖區
byte[] outbyte=new byte[buffersize];
//用于記錄已經讀取的字節數
long reval;
//字段中的索引,從這里開始讀取操作
long startindex;
//filestream對象將封裝的文件的相對路徑或絕對路徑
string [email protected]"c:/worddata.doc";
conn.open();
sqldatareader reader;
reader=cmd.executereader();
while (reader.read())
{
fs=new filestream(filepath,filemode.openorcreate,fileaccess.write);
bw=new binarywriter(fs);
startindex=0;
//將字節流讀入outbyte緩沖區中并返回讀取的字節數
reval=reader.getbytes(0,startindex,outbyte,0,buffersize);
//當讀取的字節流達到緩沖區允許的最大長度時要卸載緩沖區內的數據并將數據寫入文件
while (reval==buffersize)
{
bw.write(outbyte);
bw.flush();
//重新設定開始讀取的位置,并繼續讀取和寫數據
startindex+=buffersize;
reval=reader.getbytes(0,startindex,outbyte,0,buffersize);
}
//將緩沖區內最后剩余的數據寫入文件
bw.write(outbyte,0,(int)reval-1);
bw.flush();
bw.close();
fs.close();
}
reader.close();
conn.close();
}
此時將按照filepath中指定的路徑和名稱重新生成word文檔。可以在filepath中根據具體情況指定生成的word文檔的名稱和路徑。
(4) 打開word文檔
在打開word文檔這一部分暫時并沒有找到通過button按鈕直接打開word的有效辦法,但我們可以hyperlink控件,只要將hyperlink控件的navigateurl屬性指向word文檔的物理路徑就可以了。
新聞熱點
疑難解答
圖片精選