惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
SecWiki News
SecWiki News
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
量子位
M
MIT News - Artificial intelligence
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
TaoSecurity Blog
TaoSecurity Blog
博客园 - 【当耐特】
H
Heimdal Security Blog
腾讯CDC
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News: Ask HN
Hacker News: Ask HN
S
Schneier on Security
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
博客园 - 司徒正美
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threatpost
月光博客
月光博客
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
T
Troy Hunt's Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
D
DataBreaches.Net
O
OpenAI News
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
小众软件
小众软件
V
Vulnerabilities – Threatpost
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
T
The Exploit Database - CXSecurity.com
Martin Fowler
Martin Fowler
美团技术团队
P
Privacy International News Feed

博客园 - lemontree

SQL SERVER学习计划 新的开始 C#.NET禁止一个程序启动多个实例 - lemontree - 博客园 MDI窗体,子窗体在父窗体中最大化,如果子窗体已经打开则显示,不重复打开窗体 winform里c#验证用户正确后 怎么打开新窗口时关闭登陆窗口 Are You Going To Scarborough Fair中文歌词 安装VS2005 SP1失败 (转载)浅析HTTP协议 (转载)你是合格的程序员吗?—合格程序员应该具备的12种能力 夯实基础,从HTML开始 SQLserver2000〔Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server不存在或访问被拒绝 压缩数据库日志文件 RDLC报表(一) [转载]OWC做电子表格和图表的试验 .net 2.0 Configuration Error 浅谈ASP.NET的内部机制(一) seo专题之开篇有益 引用Microsoft.Office.Interop.Excel出现的问题 妇女节各人的不同回复
OWC生成Excel的效能优化
lemontree · 2009-03-09 · via 博客园 - lemontree

转自:http://www.cnblogs.com/leonny/,作者:leonny.

优化前的代码, 从DataTable导入1000笔数据要差不多10分钟,有时候还会超时或出错:

public void WriteDataToSpreadsheet2(SpreadsheetClass p_spreadsheet, DataTable p_dt, 
    
int p_iRow, int p_iCol, bool p_bWithCaption, int p_iStaredRecord, 
    
int p_iLimited, int[] p_iTextColumns)
{
    Worksheet f_sheet 
= p_spreadsheet.ActiveSheet;
    
int f_iRowCount = 0;
    
int f_iTotalRow = 0;
    
int f_iMaxRow = 65535;

    
int f_iRow, f_iCol, f_iDtColumn;

    f_iRow 
= p_iRow;
    f_iCol 
= p_iCol;
    
//使用标题
    if (p_bWithCaption == true)
    
{
        
foreach (DataColumn f_col in p_dt.Columns)
        
{
            f_sheet.Cells[f_iRow, f_iCol] 
= f_col.Caption;
            f_iCol
++;
        }

        f_iRow
++;
        f_iTotalRow
++;

        f_iCol 
= p_iCol;
    }


    
foreach (DataRow f_row in p_dt.Rows)
    
{
        f_iDtColumn 
= 0;
        
foreach (DataColumn f_col in p_dt.Columns)
        
{
            
if (f_row[f_col] != DBNull.Value)
            
{
                
//注意,这里是一列一列的赋值
                if (Array.IndexOf(p_iTextColumns, f_iDtColumn) > -1)
                    f_sheet.Cells[f_iRow, f_iCol] 
= "'" + f_row[f_col].ToString();    //强制转换成字符串
                else
                    f_sheet.Cells[f_iRow, f_iCol] 
= f_row[f_col];
            }

            f_iDtColumn
++;
            f_iCol
++;
        }


        f_iRowCount
++;
        f_iTotalRow
++;

        
if (f_iTotalRow >= f_iMaxRow)
            
break;

        
if (p_iLimited > 0)
        
{
            
if (f_iRowCount >= p_iLimited)
                
break;
        }

        f_iRow
++;
        f_iCol 
= p_iCol;
    }

    
return;
}

 优化后的代码, 从DataTable导入60000(注意,是六万)笔数据, 只要不到两分钟.

 1public void WriteDataToSpreadsheet(SpreadsheetClass p_spreadsheet, DataTable p_dt,
 2    int p_iRow, int p_iCol, bool p_bWithCaption, int p_iStaredRecord, 
 3    int p_iLimited, int[] p_iTextColumns)
 4{
 5    Worksheet f_sheet = p_spreadsheet.ActiveSheet;
 6    int f_iRowCount = 0;
 7    int f_iTotalRow = 0;
 8    int f_iMaxRow = 65535;
 9
10    int f_iRow, f_iCol, f_iDtColumn;
11
12    f_iRow = p_iRow;
13    f_iCol = p_iCol;
14
15    if (p_bWithCaption == true)
16    {
17        foreach (DataColumn f_col in p_dt.Columns)
18        {
19            f_sheet.Cells[f_iRow, f_iCol] = f_col.Caption;
20            f_iCol++;
21        }

22        f_iRow++;
23        f_iTotalRow++;
24
25        f_iCol = p_iCol;
26    }

27
28    string[] A2Z = new string[26"A""B""C""D""E""F""G"
29        "H""I""J""K""L""M""N""O""P""Q""R",
30        "S""T""U""V""W""X""Y""Z" }
;
31    List<string> A2ZZ = new List<string>();
32    A2ZZ.AddRange(A2Z);
33    foreach (string en in A2Z)
34    {
35        foreach (string en2 in A2Z)
36        {
37            A2ZZ.Add(en + en2);
38        }

39    }

40    string lastColumnName = A2ZZ[p_dt.Columns.Count - 1];
41
42    List<object[,]> list = new List<object[,]>();
43    Range r = f_sheet.get_Range("A" + f_iRow.ToString(), lastColumnName + f_iRow.ToString());
44    int row = p_dt.Rows.Count;
45    int col = p_dt.Columns.Count;
46
47    if (row > 0)
48    {
49        //先将每一行资料放入一个数组,然后再放入清单
50        for (int i = 0; i < row; i++)
51        {
52            object[,] objData = new Object[1, col];
53            for (int j = 0; j < col; j++)
54            {
55                if (p_dt.Rows[i][j] != DBNull.Value)
56                {
57                    if (Array.IndexOf(p_iTextColumns, j) > -1)
58                        objData[0, j] = "'" + p_dt.Rows[i][j].ToString();
59                    else
60                        objData[0, j] = p_dt.Rows[i][j];
61                }

62                else objData[0, j] = "";
63            }

64            list.Add(objData);
65        }

66    }

67    object m_objOpt = System.Reflection.Missing.Value;
68    for (int i = 0; i < row; i++)
69    {
70        //直接到一个区间,然后对区间直接赋数组作为值, 这是真正提速的地方< span style="color: #008000;">
71        Range r2 = r.get_Range("A" + (f_iRowCount+1).ToString(), lastColumnName + (f_iRowCount+1).ToString());
72        r2.set_Value(m_objOpt, list[i]);
73
74        f_iRowCount++;
75        f_iTotalRow++;
76
77        if (f_iTotalRow >= f_iMaxRow)
78            break;
79
80        if (p_iLimited > 0)
81        {
82            if (f_iRowCount >= p_iLimited)
83                break;
84        }

85        f_iRow++;
86        f_iCol = p_iCol;
87    }

88    return;
89}
90

上面一些代码是有其他用的, 大家只要看注释那块的就行了. 人太懒, 不好意思. 呵呵.

这个方法只是我在项目中使用的代码, 时间比较紧, 肯定还有更快的方法, 如果各位有更好的方法, 请赐教.