OpenXML将值写为字符串,并在转换为数字时值更改

时间:2017-01-12 15:42:59

标签: c# excel openxml

我使用OpenXML将一些数据写入Excel。我已成功设法将所有数据输入到电子表格中,但当我这样做时,所有数据都是字符串格式。这是因为我主要使用MSDN上提供的示例代码,并将数据作为InsertSharedStringItem(A string)插入Excel。然而,我确实找到了将细胞转换为数字的两种方法。

第一个是简单的CellValues.Number而不是CellValues.SharedString,但这似乎会更改单元格中的所有实际值以及将它们更改为数字。一个例子就是我现在在一列中有0,它现在是5,11现在是0而21是33,这样的奇怪的东西(如果数字像0一样重复,它们都会改变为,在0' s案例,5)。显然,这不会奏效。

然后我找到了另一种在Excel中将字符串转换为数字的方法,并且找到了here(如果您点击该答案中的链接转到该用户来源,则需要添加' www。& #39;到URL)。这个解决方案的问题在于它会将所有字符串转换为双精度数,但这次的变换与第一个解决方案的变换只有双重格式。

还值得注意的是,我的第三列应该是一个字符串,并且不需要转换为数字,但无论如何都会这样做。

我正在与之合作:

private static void WriteToExcel(string[] contents, char[] desiredColumns)
{
    string filePath = @"D:\Folder\test.xlsx";
    try
    {
        using (SpreadsheetDocument StatsCollection = SpreadsheetDocument.Open(filePath, true))
        {
            string sheetName = "";
            int totalRows = contents.Length / 15;
            int contentsIndex = 0;
            for (uint indexRow = 1; indexRow < totalRows; indexRow++)
            {
                for (int indexCol = 1; indexCol < 16; indexCol++)
                {
                    sheetName = "Sheet1";
                    SharedStringTablePart shareStringPart;
                    if (StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
                    {
                        shareStringPart = StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
                    }
                    else
                    {
                        shareStringPart = StatsCollection.WorkbookPart.AddNewPart<SharedStringTablePart>();
                    }
                    int index = InsertSharedStringItem(contents[contentsIndex], shareStringPart);
                    WorkbookPart bookPart = StatsCollection.WorkbookPart;
                    Sheet mySheet = bookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).FirstOrDefault();
                    WorksheetPart sheetPart = (WorksheetPart)(bookPart.GetPartById(mySheet.Id));
                    Cell cell = InsertCellInWorksheet(desiredColumns[indexCol - 1].ToString(), indexRow, sheetPart);
                    cell.CellValue = new CellValue(index.ToString());

                    //I added the following if structure to check for numbers
                    if (IsNumeric(contents[contentsIndex].ToString()))
                    {
                        cell.DataType = new EnumValue<CellValues>(CellValues.Number);
                    }
                    else
                    {
                        cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
                    }

                    /*I removed the following lines                            
                    Stylesheet styleSheet = bookPart.WorkbookStylesPart.Stylesheet;
                    uint _doubleStyleId = createCellFormat(styleSheet, null, null, UInt32Value.FromUInt32(4));
                    cell.StyleIndex = _doubleStyleId;
                    */
                    sheetPart.Worksheet.Save();
                    contentsIndex++;
                }
            }
            Console.WriteLine("Copy Complete.");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Cannot find output Excel file.\n" + ex.Message);
    }
}

这是来自其他解决方案的createCellFormat方法。 与我的更新相关。由于我所做的更改,我不再需要此方法,但我会将其保留,因为它与原始问题有关。

private static UInt32Value createCellFormat(Stylesheet styleSheet, UInt32Value fontIndex, UInt32Value fillIndex, UInt32Value numberFormatId)
{
    CellFormat cellFormat = new CellFormat();
    if (fontIndex != null)
    {
        cellFormat.FontId = fontIndex;
    }
    if (fillIndex != null)
    {
        cellFormat.FillId = fillIndex;
    }
    if (numberFormatId != null)
    {
        cellFormat.NumberFormatId = numberFormatId;
        cellFormat.ApplyNumberFormat = BooleanValue.FromBoolean(true);
    }
    styleSheet.CellFormats.Append(cellFormat);
    UInt32Value result = styleSheet.CellFormats.Count;
    styleSheet.CellFormats.Count++;
    return result;
}

当我尝试将单元格值从字符串转换为数字时,它会按预期转换,但会更改该值。为什么会发生这种情况,如何解决这个问题,以及防止我的一列实际字符串被更改为数字?

更新

我设法通过遵循this解决方案将字符串修改为数字转换,并相应地更新了我的代码并添加了以下方法。

private static bool IsNumeric(string value)
{
    double output = 0;
    if(Double.TryParse(value, out output))
    {
        return true;
    }
    else
    {
        return false;
    }
}

现在应该是数字的所有数字都是数字,所有需要保留字符串的字符串都是字符串。但是我的数字的实际值仍在改变(数字应该是0,11是0,21是33等)

1 个答案:

答案 0 :(得分:1)

问题是CellValue只是作为字符串的索引。您应该将实际数组contents[contentsindex]用于数字,因为您希望显示该数组的内容而不是index的值。将CellValue部分添加到if..else ...语句中,如下所示。 @BlueBarren和我一起聊天。

if (IsNumeric(contents[contentsIndex]))
{
    cell.DataType = new EnumValue<CellValues>(CellValues.Number);
    cell.CellValue = new CellValue(contents[contentsIndex]);
}
else
{
    cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
    cell.CellValue = new CellValue(index.ToString());
}