我的代码,是从sf.net上down下来的vb.net的版本。该版本已经很久没有进行维护了。我将其转化到了C#版本。不过说实话,没有一个WYSWYG的ide(如excel的designer),这段代码没什么作用。写一个excel文件,太复杂了。。。
下面是SmartExcel.CS的代码,其他的代码,我都放在回复里面,请慢慢看。。。
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Genersoft.Platform.Application.SmartExcel


{

/**//// <summary>
/// Excel读写类
/// </summary>
public class SmartExcel

{
// 'the memory copy API is used in the MKI$ function which converts an integer
// 'value to a 2-byte string value to write to the file. (used by the Horizontal
// 'Page Break function).
// Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef lpvDest As String, ByRef lpvSource As Short, ByVal cbCopy As Integer)
//
[DllImport("kernel32.dll")]
private static extern void RtlMoveMemory(ref string lpvDest,ref short lpvSource,int cbCopy);
private FileStream fs;
private BEG_FILE_RECORD m_udtBEG_FILE_MARKER;
private END_FILE_RECORD m_udtEND_FILE_MARKER;
private HPAGE_BREAK_RECORD m_udtHORIZ_PAGE_BREAK;

//create an array that will hold the rows where a horizontal page break will be inserted just before.
private int[] m_shtHorizPageBreakRows;
private int m_shtNumHorizPageBreaks=1;
private void FilePut(byte[] buf)

{
fs.Write(buf,0,buf.Length);
}

private void FilePut(System.ValueType vt)

{
Type t = vt.GetType();
int size = 0;

// foreach(FieldInfo fi in t.GetFields())
// {
// size += Marshal.SizeOf(fi.FieldType);
//
// System.Diagnostics.Trace.WriteLine(fi.Name);
// }
size = Marshal.SizeOf(vt);
IntPtr p = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(vt,p,true);
byte[] buf = new byte[size];
Marshal.Copy(p,buf,0,size);

fs.Write(buf,0,buf.Length);
Marshal.FreeHGlobal(p);
}

private void FilePut(System.ValueType vt,int len)

{
int size = 0;
size = len;
IntPtr p = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(vt,p,true);
byte[] buf = new byte[size];
Marshal.Copy(p,buf,0,size);

fs.Write(buf,0,buf.Length);
Marshal.FreeHGlobal(p);
}

public bool PrintGridLines

{
set

{
try

{
PRINT_GRIDLINES_RECORD GRIDLINES_RECORD;
GRIDLINES_RECORD.opcode = 43;
GRIDLINES_RECORD.length = 2;
if(true == value)

{
GRIDLINES_RECORD.PrintFlag = 1;
}
else

{
GRIDLINES_RECORD.PrintFlag = 0;
}
FilePut(GRIDLINES_RECORD);
}
catch(Exception ex)

{
throw ex;
}
}
}
public bool ProtectSpreadsheet

{
set

{
try

{
PROTECT_SPREADSHEET_RECORD PROTECT_RECORD;
PROTECT_RECORD.opcode = 18;
PROTECT_RECORD.length = 2;
if(true == value)

{
PROTECT_RECORD.Protect = 1;
}
else

{
PROTECT_RECORD.Protect = 0;
}
if(null == fs)throw new SmartExcelOpeartionFileException();
FilePut(PROTECT_RECORD);
}
catch(Exception ex)

{
throw ex;
}
}
}
//
public void CreateFile(string strFileName)

{
try

{
if(File.Exists(strFileName))

{
File.SetAttributes(strFileName, FileAttributes.Normal);
File.Delete(strFileName);
}
fs = new FileStream(strFileName,FileMode.CreateNew);
FilePut(m_udtBEG_FILE_MARKER);
WriteDefaultFormats();
// 'create the Horizontal Page Break array

m_shtHorizPageBreakRows = new int[1]
{0};
m_shtNumHorizPageBreaks = 0;
}
catch(Exception ex)

{
throw ex;
}
}
//
public void CloseFile()

{
short x;
try

{
if(null != fs)

{
//'write the horizontal page breaks if necessary
int lLoop1,lLoop2,lTemp;

if(m_shtNumHorizPageBreaks > 0)

{
// 'the Horizontal Page Break array must be in sorted order.
// 'Use a simple Bubble sort because the size of this array would
// 'be pretty small most of the time. A QuickSort would probably
// 'be overkill.
for(lLoop1=m_shtHorizPageBreakRows.GetUpperBound(0);lLoop1>=m_shtHorizPageBreakRows.GetLowerBound(0);lLoop1--)

{
for(lLoop2=m_shtHorizPageBreakRows.GetLowerBound(0)+1;lLoop2<=lLoop1;lLoop2++)

{
if(m_shtHorizPageBreakRows[lLoop2 - 1] > m_shtHorizPageBreakRows[lLoop2])

{
lTemp = m_shtHorizPageBreakRows[lLoop2 - 1];
m_shtHorizPageBreakRows[lLoop2 - 1] = m_shtHorizPageBreakRows[lLoop2];
m_shtHorizPageBreakRows[lLoop2] = (short)lTemp;
}
}
}
//'write the Horizontal Page Break Record
m_udtHORIZ_PAGE_BREAK.opcode = 27;
m_udtHORIZ_PAGE_BREAK.length = (short)(2 + (m_shtNumHorizPageBreaks * 2));
m_udtHORIZ_PAGE_BREAK.NumPageBreaks = (short)m_shtNumHorizPageBreaks;
FilePut(m_udtHORIZ_PAGE_BREAK);
// 'now write the actual page break values
// 'the MKI$ function is standard in other versions of BASIC but
// 'VisualBasic does not have it. A KnowledgeBase article explains
// 'how to recreate it (albeit using 16-bit API, I switched it
// 'to 32-bit).
for(x = 1;x<=m_shtHorizPageBreakRows.GetUpperBound(0);x++)

{
FilePut(System.Text.Encoding.Default.GetBytes(MKI((short)(m_shtHorizPageBreakRows[x]))));
}
}
FilePut(m_udtEND_FILE_MARKER);
fs.Close();
}
}
catch(Exception ex)

{
throw ex;
}
}
private void Init()

{
// 'Set up default values for records
// 'These should be the values that are the same for every record of these types
// beginning of file
m_udtBEG_FILE_MARKER.opcode = 9;
m_udtBEG_FILE_MARKER.length = 4;
m_udtBEG_FILE_MARKER.version = 2;
m_udtBEG_FILE_MARKER.ftype = 10;

// end of file marker
m_udtEND_FILE_MARKER.opcode = 10;
}

public SmartExcel()

{
Init();
}

public void InsertHorizPageBreak(int lrow)

{
int row;
try

{
// 'the row and column values are written to the excel file as
// 'unsigned integers. Therefore, must convert the longs to integer.
if(lrow>32767 || lrow<0)row = 0;
else row = lrow-1;
m_shtNumHorizPageBreaks = m_shtNumHorizPageBreaks + 1;
m_shtHorizPageBreakRows[m_shtNumHorizPageBreaks] = row;
}
catch(Exception ex)

{
throw ex;
}
}
public void WriteValue(ValueTypes ValueType , CellFont CellFontUsed, CellAlignment Alignment, CellHiddenLocked HiddenLocked , int lrow, int lcol, object Value)

{
WriteValue(ValueType , CellFontUsed, Alignment, HiddenLocked , lrow, lcol, Value,0);
}

public void WriteValue(ValueTypes ValueType , CellFont CellFontUsed, CellAlignment Alignment, CellHiddenLocked HiddenLocked , int lrow, int lcol, object Value,int CellFormat)

{
int l;
string st;
short col,row;
try

{
// 'the row and column values are written to the excel file as
// 'unsigned integers. Therefore, must convert the longs to integer.
tInteger INTEGER_RECORD;
tNumber NUMBER_RECORD;
byte b;
tText TEXT_RECORD;
if(lrow>32767 || lrow<0)row = 0;
else row = (short)(lrow-1);
if(lcol > 32767 || lcol<0)col = 0;else col = (short)(lcol - 1);
switch(ValueType)

{
case ValueTypes.Integer:
INTEGER_RECORD.opcode = 2;
INTEGER_RECORD.length = 9;
INTEGER_RECORD.row = row;
INTEGER_RECORD.col = col;
INTEGER_RECORD.rgbAttr1 = (byte)(HiddenLocked);
INTEGER_RECORD.rgbAttr2 = (byte)(CellFontUsed + CellFormat);
INTEGER_RECORD.rgbAttr3 = (byte)(Alignment);
INTEGER_RECORD.intValue = (short)(Value);
FilePut(INTEGER_RECORD);
break;
case ValueTypes.Number:
NUMBER_RECORD.opcode = 3;
NUMBER_RECORD.length = 15;
NUMBER_RECORD.row = row;
NUMBER_RECORD.col = col;
NUMBER_RECORD.rgbAttr1 = (byte)(HiddenLocked);
NUMBER_RECORD.rgbAttr2 = (byte)(CellFontUsed + CellFormat);
NUMBER_RECORD.rgbAttr3 = (byte)(Alignment);
NUMBER_RECORD.NumberValue = (double)(Value);
FilePut(NUMBER_RECORD);
break;
case ValueTypes.Text:
st = Convert.ToString(Value);
l = GetLength(st);// 'LenB(StrConv(st, vbFromUnicode)) 'Len(st$)
TEXT_RECORD.opcode = 4;
TEXT_RECORD.length = 10;
//'Length of the text portion of the record
TEXT_RECORD.TextLength = (byte)l;
// 'Total length of the record
TEXT_RECORD.length = (byte)(8 + l);
&