2

我需要有人来创建一种方法,将 Excel 电子表格中的所有单元格值转换为 2D 数组。

我正在使用 C# 中的功能区与 Excel 一起工作,但我无法让它工作。

  private string[,] GetSpreadsheetData () 
  {
        try
        {
            Excel.Application exApp =
            Globals.TSExcelAddIn.Application as Excel.Application;
            Excel.Worksheet ExWorksheet = exApp.ActiveSheet as Excel.Worksheet;
            Excel.Range xlRange = ExWorksheet.get_Range("A1","F188000");

            object[,] values = (object[,])xlRange.Value2;
            string[,] tsReqs = new string[xlRange.Rows.Count, 7];
            char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();

            for (int i = 0; i < tsReqs.GetLength(0); i++)
            {
                for (int z = 0; z < tsReqs.GetLength(1); z++)
                {
                    if(values[i+1,z+1] != null)
                        tsReqs[i, z] = values[i + 1, z + 1].ToString();
                }
            }
            return tsReqs;
        }

        catch
        {
            MessageBox.Show
                ("Excel has encountered an error. \nSaving work and exitting");
            return null;
        }
    }

另外,如果有人有更有效的方法来做到这一点,我将不胜感激。

            Excel.Range xlRange = ExWorksheet.get_Range("A1","F188000");

从 A1 一直读取到 F188000 单元格,我只是希望它继续读取,直到它到达绝对没有数据的行。

   -        Caught: "Index was outside the bounds of the array." (System.IndexOutOfRangeException)  Exception Message = "Index was outside the bounds of the array.", Exception Type = "System.IndexOutOfRangeException"    
4

4 回答 4

4

您可以考虑使用ExWorksheet.UsedRange而不是ExWorksheet.get_Range("A1","F188000")

编辑:另外,我认为如果您使用 Range 的 .Text 字段,该值会自动转换为字符串,因此此处无需使用 .Value2

Excel.Range rng = ExWorksheet.UsedRange;
int rowCount = rng.Rows.Count;
int colCount = rng.Columns.Count;

string[,] tsReqs = new string[rowCount, colCount];

for (int i = 1; i <= rowCount; i++)
{
    for (int j = 1; j <= colCount; j++)
    {
        string str = rng.Cells[i, j].Text;
        tsReqs[i - 1, j - 1] = str;
    }
}
于 2013-01-16T22:13:14.380 回答
0

尝试这个

    private static void printExcelValues(Worksheet xSheet)
    {
        Range xRng =xSheet.Cells.SpecialCells(
            XlCellType.xlCellTypeConstants);
        var arr = new string[xRng.Rows.Count,xRng.Columns.Count];
        foreach (Range item in xRng)
        {
            arr[item.Row-1,item.Column-1]=item.Value.ToString();
        }
    }

您可以使用 | 指定更多单元格类型,如 XlCellType.xlCellTypeFormulas 或您想要的任何其他类型。

于 2013-01-16T21:57:19.453 回答
0

我不得不做一些非常相似的事情。读取一个 excel 文件需要一段时间……我采取了不同的方法,但我完成了工作并获得了立竿见影的效果。

首先,我给每一列自己的数组。我将电子表格中的每一列保存为 CSV(逗号分隔)文件。用记事本打开该文件后,我能够将用逗号分隔的 942 个值复制到数组的初始化中

int[] Column1 = {300, 305, 310, ..., 5000};
                 [0]  [1]  [2]  ...  [941]

现在...如果您为每个列执行此操作,则该位置将类似于您的“电子表格”的每个“列”的“行”。

这种奇怪的方法对我来说非常有效,因为我需要将用户输入尺寸与电子表格中“宽度”列中的值进行比较,以获取有关电子表格中每个相应尺寸的信息。

注意:如果您的单元格包含字符串而不是像我这样的整数,您可以使用枚举方法:

enum column1 { thing_1, thing_2, ..., thing_n,}
                 [0]      [1]           [n]  

这是我的代码如果您想看一下:(这不是将电子表格转换为某些数组的代码-这只是几行代码,具体取决于您的列数-这是我编写的整个查找方法)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PalisadeWorld
{   
//struct to store all the positions of each matched panel size in an array 'Identities'
struct ID
    {
        public int[] Identities;
        public ID(int[] widths, int rows)
        {   
            //Column1 from spreadsheet
            int[] allWidths = { 300, 305, 310, 315, 320, 325, 330, ..., 5000 };
            int i,j;
            int[] Ids = new int[rows];

            for (i = 0; i < rows; i++)
            {
                for (j = 0; j < 941; j++)
                {
                    if (widths[i] == allWidths[j])
                    {
                        Ids[i] = j;
                        break;
                    }
                }
            }
            this.Identities = Ids;
        }
        public override string ToString()
        {
            string data = String.Format("{0}", this.Identities);
            return data;
        }
    }

class LookUpSheet
{   
    //retrieve user input from another class
    public int[] lookUp_Widths {get; set;}
    public int lookUp_Rows { get; set; }

    //Method returning desired values from Column2
    public int[] GetNumPales1()
    {
        //column2
        int[] all_numPales = { 2, 2, 2, 2, 2, 2, 2, 2, 2, ..."goes on till [941]"...};
        int[] numPales = new int[lookUp_Rows];

        ID select = new ID(lookUp_Widths, lookUp_Rows);

        for (int i = 0; i < lookUp_Rows; i++)
        {
            numPales[i] = all_numPales[select.Identities[i]];
        }

        return numPales;
    }
    //Method returning desired values from Column3
    public int[] GetBlocks1()
    {
        //column3
        int[] all_blocks = { 56, 59, 61, 64, 66, 69, 71, 74, "goes on till [941]"...};
        int[] blocks = new int[lookUp_Rows];

        ID select = new ID(lookUp_Widths, lookUp_Rows);

        for (int i = 0; i < lookUp_Rows; i++)
        {
            blocks[i] = all_blocks[select.Identities[i]];
        }
        return blocks;
    }

...

继续浏览我的电子表格的每一列

真的希望这可以帮助某人。干杯

于 2013-03-06T14:03:23.107 回答
0

您的数组大小不同。您的值来自A1:F1880006 列,但您正在循环遍历tsReqs7 列的列。看起来您正在尝试考虑values将是一个基于 1 的数组的事实,但没有正确考虑这一点。

将声明更改tsReqs为:

string[,] tsReqs = new string[xlRange.Rows.Count, 6];

你应该没事。

于 2013-01-16T22:02:31.497 回答