Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Excel.Range.set_Value()指定单个单元格的格式_C#_.net_Excel_Interop - Fatal编程技术网

C# 如何使用Excel.Range.set_Value()指定单个单元格的格式

C# 如何使用Excel.Range.set_Value()指定单个单元格的格式,c#,.net,excel,interop,C#,.net,Excel,Interop,当我将整个表格写入excel工作表时,我知道要同时处理整个范围,而不是写入单个单元格。但是,在填充要导出到Excel的数组时,是否有方法指定格式 我现在做的是: object MissingValue = System.Reflection.Missing.Value; Excel.Application excel = new Excel.Application(); int rows = 5; int cols = 5; int someVal; Excel.Worksheet sheet

当我将整个表格写入excel工作表时,我知道要同时处理整个范围,而不是写入单个单元格。但是,在填充要导出到Excel的数组时,是否有方法指定格式

我现在做的是:

object MissingValue = System.Reflection.Missing.Value;
Excel.Application excel = new Excel.Application();
int rows = 5;
int cols = 5;
int someVal;

Excel.Worksheet sheet = (Excel.Worksheet)excel.Workbooks.Add(MissingValue).Sheets[1];
Excel.Range range = sheet.Range("A1", sheet.Cells(rows,cols));
object[,] rangeData = new object[rows,cols];
for(int r = 0; r < rows; r++)
{
    for(int c = 0; c < cols; c++)
    {
        someVal = r + c;
        rangeData[r,c] = someVal.ToString();
    }
}
range.set_Value(MissingValue, rangeData);
object MissingValue=System.Reflection.Missing.Value;
Excel.Application Excel=新建Excel.Application();
int行=5;
int cols=5;
int-someVal;
Excel.Worksheet sheet=(Excel.Worksheet)Excel.Workbooks.Add(MissingValue.Sheets[1];
Excel.Range范围=sheet.Range(“A1”,sheet.Cells(行,列));
对象[,]范围数据=新对象[行,列];
对于(int r=0;r
现在假设我想把其中一些数字格式化为百分比。我知道我可以逐个单元格返回并更改格式,但这似乎违背了使用单个Range.set_Value()调用的全部目的。我是否可以使rangeData[,]结构包含格式信息,以便在调用set_Value()时,单元格的格式符合我的要求


为了澄清,我知道我可以为整个Excel.Range对象设置格式。我想要的是为每个单元格指定不同的格式,在内部循环中指定。

您可以对范围应用格式,然后用无法在
对象[,]中指定格式的值填充它。
数组

您可以通过

for(int r = 0; r < rows; r++)
{
    for(int c = 0; c < cols; c++)
    {
       Excel.Range r2 = sheet.Cells( r, c );
       r2.xxxx = "";
    }
}
for(int r=0;r
一旦你有了
r2
,你就可以随心所欲地更改单元格格式。

因此,这是迄今为止我找到的最好的“解决方案”。这不是我想要的涅磐,但它比为每个细胞单独设置格式要快得多

// 0-based indexes
static string RcToA1(int row, int col)
{
    string toRet = "";
    int mag = 0;
    while(col >= Math.Pow(26, mag+1)){mag++;}
    while (mag>0)
    {
        toRet += System.Convert.ToChar(64 + (byte)Math.Truncate((double)(col/(Math.Pow(26,mag)))));
        col -= (int)Math.Truncate((double)Math.Pow(26, mag--));
    }
    toRet += System.Convert.ToChar(65 + col);
    return toRet + (row + 1).ToString();
}

static Random rand = new Random(DateTime.Now.Millisecond);
static string RandomExcelFormat()
{
    switch ((int)Math.Round(rand.NextDouble(),0))
    {
        case 0: return "0.00%";
        default: return "0.00";
    }
}


struct ExcelFormatSpecifier
{
    public object NumberFormat;
    public string RangeAddress;
}

static void DoWork()
{
    List<ExcelFormatSpecifier> NumberFormatList = new List<ExcelFormatSpecifier>(0);

    object[,] rangeData = new object[rows,cols];
    for(int r = 0; r < rows; r++)
    {
        for(int c = 0; c < cols; c++)
        {
            someVal = r + c;
            rangeData[r,c] = someVal.ToString();
            NumberFormatList.Add(new ExcelFormatSpecifier
                {
                    NumberFormat = RandomExcelFormat(),
                    RangeAddress = RcToA1(rowIndex, colIndex)
                });
        }
    }
    range.set_Value(MissingValue, rangeData);

    int max_format = 50;
    foreach (string formatSpecifier in NumberFormatList.Select(p => p.NumberFormat).Distinct())
    {
        List<string> addresses = NumberFormatList.Where(p => p.NumberFormat == formatSpecifier).Select(p => p.RangeAddress).ToList();
        while (addresses.Count > 0)
        {
            string addressSpecifier = string.Join(",",     addresses.Take(max_format).ToArray());
            range.get_Range(addressSpecifier, MissingValue).NumberFormat = formatSpecifier;
            addresses = addresses.Skip(max_format).ToList();
        }
    }
}
//基于0的索引
静态字符串RcToA1(整数行,整数列)
{
字符串toRet=“”;
int-mag=0;
而(col>=Math.Pow(26,mag+1)){mag++;}
while(mag>0)
{
toRet+=System.Convert.ToChar(64+(字节)Math.Truncate((双精度)(col/(Math.Pow(26,mag ')));
col-=(int)Math.Truncate((double)Math.Pow(26,mag-);
}
toRet+=系统转换为ToChar(65+列);
返回toRet+(行+1).ToString();
}
静态随机兰德=新随机数(DateTime.Now.毫秒);
静态字符串格式()
{
开关((int)Math.Round(rand.NextDouble(),0))
{
案例0:返回“0.00%”;
默认值:返回“0.00”;
}
}
结构ExcelFormatSpecifier
{
公共对象编号格式;
公共字符串地址;
}
静态空心榫钉()
{
列表编号格式列表=新列表(0);
对象[,]范围数据=新对象[行,列];
对于(int r=0;rp.NumberFormat.Distinct())中的字符串格式说明符)
{
List addresses=NumberFormatList.Where(p=>p.NumberFormat==formatSpecifier)。选择(p=>p.RangeAddress.ToList();
而(addresses.Count>0)
{
string addressSpecifier=string.Join(“,”,addresses.Take(max_格式).ToArray());
range.get_range(addressSpecifier,MissingValue).NumberFormat=formatSpecifier;
地址=地址.Skip(max_格式).ToList();
}
}
}
基本上,我在NumberFormatList中为每个单元格保留了一个格式信息列表(每个元素还保存其应用范围的A1样式地址)。最初的想法是,对于工作表中的每种不同格式,我应该能够构建一个Excel.Range,只包含这些单元格,并在一次调用中将格式应用于该范围。这将使对NumberFormat的访问次数从(可能)数千次减少到只有几次(无论您有多少种不同的格式)

然而,我遇到了一个问题,因为你显然不能从任意长的单元格列表中构造一个范围。经过一些测试,我发现限制在50到100个单元格之间,可以用来定义任意范围(如range.get_range(“A1,B1,C1,A2,AA5,…))。因此,一旦我得到了要应用格式的所有单元格的列表,我就有了最后一个while()循环,该循环一次将格式应用于其中的50个单元格


这并不理想,但它仍然将NumberFormat的访问次数减少了50倍,这是非常重要的。在没有任何格式信息的情况下构建电子表格(仅使用range.set_Value())大约需要3秒。当我一次应用50个单元格的格式时,时间会延长到10秒左右。当我将格式信息单独应用到每个单元格时,电子表格需要2分钟才能完成构建!

我意识到这将完成工作,但我正试图保持对abs的Excel互操作的调用次数绝对最小值。在内部循环中应用格式将有效,但会非常慢。虽然我接受了自己的答案,但我决定使用Excel automation来编写文件是一个糟糕的计划。接下来,我将使用Excel软件包库直接编写.xlsx文件+一段漂亮的代码;)我不知道可以使用formatSpecifier来设置单元格范围。