在 C# 2.0 中编写 excel 文件而不使用任何第三方 dlls/interop/sdk

Posted

技术标签:

【中文标题】在 C# 2.0 中编写 excel 文件而不使用任何第三方 dlls/interop/sdk【英文标题】:Write excel file in C# 2.0 without using any third party dlls/interop/sdk 【发布时间】:2013-08-23 23:11:12 【问题描述】:

我想用 C# 编写一个 excel 文件 (xls/xlsx)。

约束: 我不想在写作时使用以下内容: 1. 第三方 dll(我的客户端不允许我使用第三方 dll) 2. SDK(同上原因,不能下载) 3.不允许在目标服务器上使用互操作,因为没有安装office。 4. OpenXml

信息: 1. 使用VS 2005。 2. 使用 ASP.Net (C# 2.0)

【问题讨论】:

...并且没有电脑 在某些时候,您是专业人士,而他们是客户。他们会提供一种需求,你来满足这种需求。他们说“你必须这样做而不是那样”是疯狂的,否则他们最好自己编码......(除非这是秘密的某种硬件任务,呵呵) 【参考方案1】:

编写一个可以直接用Excel打开的csv文件。

【讨论】:

@Amit 我了解客户的请求是客户的请求,但是 Excel 可以天真地打开 CSV 或文本制表符分隔 (.txt) 文件...我不确定,但是我认为您需要一个库来执行实际的 xls/xlsx,因为如果您尝试自己动手,那么您需要深入了解该规范。 (ps:xlsx 是基于 XML 的调整) 假设他们有一个副本,他们必须在 Excel 中打开文本文件,并将其保存为 Excel。【参考方案2】:

我想这会对你有所帮助

    [DllImport("user32.dll")]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    public DataTable readexcelV1(string path, bool isHeader, params string[] sheetname)
    

        bool isFirstTime = true;
        string filePath = path;
        Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
        ExcelApp.Visible = false;
        Microsoft.Office.Interop.Excel.Workbook wb = ExcelApp.Workbooks.Open(filePath, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

        string ActiveSheetName = "";
        if (sheetname.Count() == 0)
            ActiveSheetName = ((dynamic)wb).ActiveSheet.Name;
        else
            ActiveSheetName = Convert.ToString(sheetname[0]);

        Microsoft.Office.Interop.Excel.Worksheet sh = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets[ActiveSheetName];
        //////////////////////////
        excellt.Range excelRange = sh.UsedRange;
        Int32 Userows = excelRange.Rows.Count;
        Int32 Usecolumns = excelRange.Columns.Count;
        int Pointrow = 1;
        int expVar = 75000;
        int Pointcolumn = expVar;
        int co = 0;
        int r = 0;
        expVar = Userows > expVar ? expVar : Userows;
        decimal lcount = Convert.ToDecimal(Userows) / Convert.ToDecimal(expVar);
        Int32 lcountint = Convert.ToInt32(Math.Ceiling(lcount));
        DataTable dt = new DataTable();
        if (isHeader == true)
        
            int duplicateColum = 1;
            for (int j = 1; j <= excelRange.Columns.Count; j++) // Header Names
            
                if (excelRange.Cells[1, j].Value2 != null)
                
                    if (!dt.Columns.Contains(Convert.ToString(excelRange.Cells[1, j].Value2).Trim()))
                    
                        dt.Columns.Add(Convert.ToString(excelRange.Cells[1, j].Value2).Trim());
                    
                    else
                    
                        dt.Columns.Add(Convert.ToString(excelRange.Cells[1, j].Value2).Trim() + duplicateColum.ToString());
                        duplicateColum++;
                    
                
                else
                
                    dt.Columns.Add("Column" + j.ToString());
                    duplicateColum++;
                
            
        
        else
        
            for (int j = 1; j <= excelRange.Columns.Count; j++) // Header Names
                dt.Columns.Add("Column" + j.ToString());
        

        string cell = string.Empty;
        string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int colCharsetLen = colCharset.Length;
        if (dt.Columns.Count > colCharsetLen)
        
            cell = colCharset.Substring(
                (dt.Columns.Count - 1) / colCharsetLen - 1, 1);
        

        cell += colCharset.Substring(
                (dt.Columns.Count - 1) % colCharsetLen, 1);


        for (int i = 0; i < lcountint; i++)
        
            string cell1 = "A" + Convert.ToString(Pointrow);
            string cell2 = cell + Convert.ToString(Pointcolumn);
            excellt.Range rng = sh.get_Range(cell1, cell2);
            object[,] x = (object[,])rng.get_Value(excellt.XlRangeValueDataType.xlRangeValueDefault);
            int NumRow = isHeader == true && isFirstTime == true ? 2 : 1;

            int loopUpto = Userows > expVar ? (Pointcolumn - Pointrow) : expVar;
            loopUpto += 2;

            isFirstTime = false;
            while (NumRow < loopUpto)
            
                dt.Rows.Add();
                co = 0;
                for (int c = 1; c <= Usecolumns; c++)
                
                    dt.Rows[r][co] = Convert.ToString(x[NumRow, c]);
                    co++;
                
                NumRow++;
                r++;
            
            Pointrow += expVar;
            Pointcolumn += expVar;
            Pointcolumn = (Pointcolumn >= Userows) ? Userows : Pointcolumn;

            progressBar1.Value += 10;
        

        GC.Collect();
        GC.WaitForPendingFinalizers();
        if (ExcelApp != null)
        
            ExcelApp.Quit();
            int hWnd = ExcelApp.Application.Hwnd;
            uint processID; GetWindowThreadProcessId((IntPtr)hWnd, out processID);
            Process[] procs = Process.GetProcessesByName("EXCEL");
            foreach (Process p in procs)
            
                if (p.Id == processID)
                    p.Kill();
            
            Marshal.FinalReleaseComObject(ExcelApp);
        

        return dt;
    

【讨论】:

【参考方案3】:

我希望客户按小时付费,因为这些都是愚蠢的解决方案限制(除非有情有可原)

然而,Excel 电子表格的 XML 格式实际上编写代码并没有那么糟糕,较新版本的 EXcel 将打开一个 .xml 文件并将其视为电子表格。您可以在 .xml 格式中嵌入格式、标题等,并且由于 XML 是结构化的,因此它比通过代码写入大量字节的数据更易于维护。

使用 excel,以正确的格式创建一个文档,将其用作模板,然后反复调整直到它根据需要运行。确保你有一个体面的 XML 编辑器和足够的耐心。

【讨论】:

【参考方案4】:

我认为 Text-Tab Delimited 将比尝试使用 CSV 生成器更简单、更快速地编写。如果您在设计阶段不小心并仔细检查数据的所有预期变化,CSV 有时可能会出现奇怪的怪癖。 CSV 将需要文本限定符等。除非您希望您的数据到处都有制表符,否则制表符分隔的文件很容易做到。

【讨论】:

以上是关于在 C# 2.0 中编写 excel 文件而不使用任何第三方 dlls/interop/sdk的主要内容,如果未能解决你的问题,请参考以下文章

C#自动更新Excel报表而不改变原有样式(2021.8.11)

如何在 C# 中的 JSON-RPC 2.0 中编写“参数”?

如何在.net 2.0中将数据从数据库或DataTable保存到Excel文件而没有响应

C# 如何在文本文件中添加数据而不清除原来的内容?

如何仅使用 MIN-MAX 编写 excel 公式,而不使用 IF

如何在 C# 的线程中以编程方式复制 Excel 文件时修复访问拒绝错误