2017-01-12 26 views
1

私はExcelにデータを書き込むためにOpenXMLを使用しています。私はスプレッドシートにすべてのデータを入力することに成功しましたが、私はそれをすべてString形式にしています。これは、私がほとんどMSDNで利用可能なサンプルコードを利用しており、ExcelにデータをInsertSharedStringItem(A string)として挿入するためです。私はしかし、細胞を数に変換する2つの方法を見つけました。OpenXMLは値を文字列として書き込み、数値に変換して値を変更します

最初はCellValues.SharedStringの代わりに単純CellValues.Numberでしたが、それはセルのすべての実際の値を変更し、数値に変更するようです。例として、今は5の列に0があり、11は現在0で21は33です。そのような奇妙なものです(数字が0のように繰り返されると、0の場合はすべて5に変わります)。明らかにそれは動作しません。

次に、Excelで文字列を数値に変換する別の方法が見つかりました。here(その回答のリンクをクリックしてそのユーザーのソースに移動すると、URLに 'www。'を追加する必要があります)が見つかりました。このソリューションの問題点は、すべての文字列を倍精度に変換することですが、値は今回の倍精度形式の最初の解と同じ変種になります。

私の3番目の列は文字列であると考えられ、数字に変換する必要はありませんが、それはとにかく行います。

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; 
} 

セルの値を文字列から数値に変換しようとすると、期待通りに変換されますが値が変更されます。なぜこれが起こっているのですが、実際の文字列の1つの列が数値に変更されないように、この問題を解決するにはどうすればよいですか?

更新:

私はthisソリューションに従うことによって数への変換文字列を修正するために管理し、私はそれに応じて自分のコードを更新し、次のメソッドを追加しました。

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

これで、数字でなければならないものはすべて数字です。文字列のままにする必要があるものはすべて文字列です。しかし、私の数字の実際の値はまだ変更されています(数値は0、5は11、21は33などです)

+0

私はMSDNへのリンクが十分であることを期待していましたが、私はこれらの2つの方法も同様に投稿できます。 – BlueBarren

+0

いいえ、私はそこに見せてくれるのを忘れました。 – JohnG

答えて

1

問題はCellValueが文字列としてのインデックスにすぎないということでした。 indexの値ではなくその配列の内容を表示したいので、実際の配列contents[contentsindex]を数値として使用する必要があります。下記のように、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()); 
} 
関連する問題