与灵感之源的vb.net对应的SmartExcel的C#版本

我的代码,是从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);
   &