公告

國明的網路筆記

2014年7月10日 星期四

解決 GridView 內容的資料匯出成 Excel 檔時產生的問題:

我要將 GridView 的 HTML內容的資料匯出成 Excel 檔,這部份的功能可以透過Control.RenderControl的方式
Control.RenderControl :
輸出伺服器控制項內容,並在啟用追蹤功能的情況下,儲存控制項的追蹤資訊。
http://msdn.microsoft.com/zh-tw/library/system.web.ui.control.rendercontrol(VS.80).aspx
將 GridView 內的資料匯出成 Excel 檔的程式碼
    protected void Button2_Click(object sender, EventArgs e)
    {
        Response.ClearContent();
        
string excelFileName = "測試Excel檔案.xls";
        Response.AddHeader(
"content-disposition", "attachment;filename=" + Server.UrlEncode(excelFileName));
        Response.ContentType = 
"application/excel";
        System.IO.StringWriter stringWrite = 
new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = 
new HtmlTextWriter(stringWrite);
        GridView1.RenderControl(htmlWrite);
        Response.Write(stringWrite.ToString());
        Response.End();
    }

在這邊會遇到兩個問題
問題1. 產生型別 'GridView' 的控制項 'GridView1' 必須置於有 runat=server 的表單標記之中的問題
這個問題我在 topcat 大大的Bog得到解決方式,加上此段程式碼即可
    public override void VerifyRenderingInServerForm(Control control) 
    { 
        // '處理'GridView' 的控制項 'GridView' 必須置於有 runat=server 的表單標記之中   
    }  
關於此錯誤以及遇到網頁中有分頁時的處理方式,可以參考 topcat 大大的Blog

問題2. 當 GridView 中有中文字時,使用上述的程式碼所匯出的Excel會有中文亂碼
解決此問題的方式參考 MSDN 論壇上 LOLOTA 大大的方法,加上這段程式碼解決轉碼問題即可
Response.Write("<meta http-equiv=Content-Type content=text/html;charset=utf-8>");

完整的程式碼如下 :
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
 
public partial class _Default : System.Web.UI.Page
{
    
protected void Button2_Click(object sender, EventArgs e)
    {
        Response.ClearContent();
        Response.Write(
"<meta http-equiv=Content-Type content=text/html;charset=utf-8>");
        
string excelFileName = "測試Excel檔案.xls";
        Response.AddHeader(
"content-disposition", "attachment;filename=" + Server.UrlEncode(excelFileName));
        Response.ContentType = 
"application/excel";
        System.IO.StringWriter stringWrite = 
new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = 
new HtmlTextWriter(stringWrite);
        GridView1.RenderControl(htmlWrite);
        Response.Write(stringWrite.ToString());
        Response.End();
    }

    
public override void VerifyRenderingInServerForm(Control control) 
    {
        
// '處理'GridView' 的控制項 'GridView' 必須置於有 runat=server 的表單標記之中   
    } 
}

問題3. 當檔名中有中文字時,使用上述的程式碼所匯出的Excel會有中文亂碼

解決方法就是利用HttpUtility.UrlEncode來進行轉碼動作。
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", System.Web.HttpUtility.UrlEncode(FileName & ".xls", System.Text.Encoding.UTF8)))

問題4. RegisterForEventValidation 只能在 Render(); 期間呼叫。

這項網路上也有許多文章提出一個解法,大部分的人提出要在的標籤中,修改AutoEventWireup="true"並增加EnableEventValidation = "false";另一個人提出只需要增加EnableEventValidation = "false",並不需要將AutoEventWireup改為true。測試之後只需要增加EnableEventValidation = "false"屬性即可,但也有可能AutoEventWireup會解決另一個問題,還是先記錄下來吧!

問題5. 將GridView匯出excel,如果GridView有分頁的話則會發生錯誤。

  // 先解除分頁
  GridView1.AllowPaging = False;
  GridView1.DataBind();

  GridView1.RenderControl(hw);
  Response.Write(sw.ToString());
  Response.End();

  // 再設為分頁
  GridView1.AllowPaging = True;
  GridView1.DataBind();






2014年6月8日 星期日

.net發現某元件不存在於目前內容中

有些人的習慣,修改版本測試時,通常會將舊檔案加上一個數字如 xxx_1.aspx,沒將其他相關連結改過或移到別處,造成抓到舊版本而產生錯誤,像"名稱 'BtnA' 不存在於目前內容中",但設計網頁裡明明就有BtnA,所以只要將更名後的檔案移到別處後就OK了!

2013年12月22日 星期日

直接以RegEdit來設定SQL用戶端以別名網路連線


若要設定SQL用戶端網路連線,但沒有 SQL Server 所提供的公用程式時,
可以直接變更預設的網路程式庫,以RegEdit來直接設定,請移至下面登錄機碼:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo

然後新增一個類型字串的值,名稱為連線別名 。您可以使用下面列出的值來變更網路程式庫:
TCP/IP: DBMSSOCN
具名管道: DBNMPNTW
多重通訊協定 (RPC): DBMSRPCN
NWLink IPX/SPX: DBMSSPXN
AppleTalk: DBMSADSN
Banyan VINES: DBMSVINN

例如要連接一台名稱為 abc 的SQL主機,主機是透過TCP/IP協定,IP=192.168.1.1 設定值如下:
DBMSSOCN,192.168.1.1



2013年6月28日 星期五

截斷 MS SQL Server Log 檔案

幾年前,學校的選課系統的資料庫選用 MS SQL Server,因資料庫的Log檔案會無盡的擴大,常常比資料庫還要大上好幾倍,最後造成硬碟空間不足,雖然近年來,硬碟容量越來越大,已經不在發現類式問題,但Log檔案還是會造成資料讀取的速度問題,之前就索性將Log檔案給予截斷,採用 T_SQL 指令

dump transaction database_name with truncate_only
再利用工具壓縮資料庫(按右鍵->所有工作->壓縮資料庫)即可 (SQL 的壓縮有可能就是 Pack)

或

Backup Log database_name with truncate_only
DBCC ShrinkDataBase(database_name, 30, truncateonly ) --實際釋放空間, 留30%空間

// --------------------------------------
從網路上查到:
下列語法是針對MS-SQL 2000及MS-SQL 2005的截斷Scritp:
--1.截斷交易記錄
BACKUP LOG [資料庫名稱] WITH TRUNCATE_ONLY

--2.顯示資料庫檔案,找出交易記錄檔的邏輯檔名
EXEC sp_helpdb '資料庫名稱'

--3.壓縮交易記錄檔
USE 資料庫名稱
DBCC SHRINKFILE([資料庫名稱_log],2)
------------------------------------------------
--進行Log瘦身
--SQL 2000及SQL2005適用
BACKUP LOG 資料庫名稱 TO Disk='C:\LogTemp\DevLog.bak' WITH  init  --先備份Log檔
DBCC SHRINKDATABASE(資料庫名稱,30,NOTRUNCATE)    -- 先挪空間,NoTruncate表示不截斷,30表示留30%大小
DBCC SHRINKDATABASE(資料庫名稱,30,TRUNCATEONLY ) --實際釋放空間

--SQL 2008 Log瘦身適用
-- SQL 2008要截斷Log必須先改成簡單模式.
ALTER DATABASE 資料庫名稱  
    SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (資料庫Log名稱, 100);
GO
-- Reset the database recovery model.
ALTER DATABASE資料庫名稱  
    SET RECOVERY FULL;
GO
// --------------------------------------------

-- 總整理 --

SQL SERVER 2008

USE [資料庫名稱]
GO
ALTER DATABASE [資料庫名稱] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC SHRINKFILE(記錄檔邏輯名稱, 1)
ALTER DATABASE [資料庫名稱] SET RECOVERY FULL WITH NO_WAIT
GO

邏輯名稱可在資料庫上按右鍵=>[屬性]=>[檔案]中查看,注意邏輯名稱不一定會和檔名相同,例如:

USE [TestDB]
GO
ALTER DATABASE [TestDB] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC SHRINKFILE(TestDB_log, 1)
ALTER DATABASE [TestDB] SET RECOVERY FULL WITH NO_WAIT
GO

----------------------------------------------------------------------

之前的版本(SQL SERVER 2000, 2005)的話可以使用以下指令:

USE [資料庫名稱]
GO
DBCC SHRINKFILE(記錄檔邏輯名稱, 1)
BACKUP LOG [資料庫名稱] WITH TRUNCATE_ONLY
DBCC SHRINKFILE(記錄檔邏輯名稱, 1)
GO

例如:

USE [TestDB]
GO
DBCC SHRINKFILE(TestDB_log, 1)
BACKUP LOG [TestDB] WITH TRUNCATE_ONLY
DBCC SHRINKFILE(TestDB_log, 1)
GO
----------------------------------------------------------------------