2016-07-25 1 views
1

Я пытаюсь читать файлы Excel через OpenXML и искать вывод в CSV. В настоящее время он считывает каждую ячейку отдельной строкой (из-за записи) или одной строкой (при использовании записи). Каков наилучший способ чтения и вывода в табличном формате, например, в Excel? Есть ли встроенная функция OpenXML, которую я могу использовать для этого?Чтение файлов Excel с использованием OpenXML

static void Main(string[] args) 
{ 
     String xlDocName = @"C:\Users\xlp111\source.xlsx"; 

     using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(xlDocName, false)) 
     { 
      WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart; 
      string cellValue = string.Empty; 
      foreach(WorksheetPart worksheetPart in workbookPart.WorksheetParts) 
      { 
       OpenXmlReader reader = OpenXmlReader.Create(worksheetPart); 

       while (reader.Read()) 
       { 
       if (reader.ElementType == typeof(Row)) 
       { 
        reader.ReadFirstChild(); 

        do 
        { 
        if (reader.ElementType == typeof(Cell)) 
        { 
         Cell c = (Cell)reader.LoadCurrentElement(); 

         if (c.DataType != null && c.DataType == CellValues.SharedString) 
         { 
         SharedStringItem ssi = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(int.Parse(c.CellValue.InnerText)); 
         cellValue = ssi.Text.Text; 
         Console.WriteLine(cellValue); 
         } 
        } 
        }      
        while (reader.ReadNextSibling()); 
       } 
       } 
      } 
      Console.ReadLine(); 
     } 
    } 
} 
+0

Родственный пост [здесь] (https://stackoverflow.com/q/5115257/465053). – RBT

ответ

3

Edit:

Использование Open XML SDK для Microsoft Office

установки V2 из: https://www.microsoft.com/en-eg/download/details.aspx?id=5124&wa=wsignin1.0

(или V2.5)

Следующий класс конвертировать лист excel в CSV-файл с помощью делиметра

//reference library 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 


public class OpenXmlExcel 
{ 
public void ExcelToCsv(string source, string target, string delimiter = ";", bool firstRowIsHeade = true) 
{ 
    var dt = ReadExcelSheet(source, firstRowIsHeade); 
    DatatableToCsv(dt, target, delimiter); 

} 

private void DatatableToCsv(DataTable dt, string fname, string delimiter = ";") 
{ 

    using (StreamWriter writer = new StreamWriter(fname)) 
    { 
     foreach (DataRow row in dt.AsEnumerable()) 
     { 
      writer.WriteLine(string.Join(delimiter, row.ItemArray.Select(x => x.ToString())) + delimiter); 
     } 
    } 

} 

List<string> Headers = new List<string>(); 


private DataTable ReadExcelSheet(string fname, bool firstRowIsHeade) 
{ 

    DataTable dt = new DataTable(); 
    using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fname, false)) 
    { 
     //Read the first Sheets 
     Sheet sheet = doc.WorkbookPart.Workbook.Sheets.GetFirstChild<Sheet>(); 
     Worksheet worksheet = (doc.WorkbookPart.GetPartById(sheet.Id.Value) as WorksheetPart).Worksheet; 
     IEnumerable<Row> rows = worksheet.GetFirstChild<SheetData>().Descendants<Row>(); 

     foreach (Row row in rows) 
     { 
      //Read the first row as header 
      if (row.RowIndex.Value == 1) 
      { 
       var j = 1; 
       foreach (Cell cell in row.Descendants<Cell>()) 
       { 
        var colunmName = firstRowIsHeade ? GetCellValue(doc, cell) : "Field" + j++; 
        Console.WriteLine(colunmName); 
        Headers.Add(colunmName); 
        dt.Columns.Add(colunmName); 
       } 
      } 
      else 
      { 
       dt.Rows.Add(); 
       int i = 0; 
       foreach (Cell cell in row.Descendants<Cell>()) 
       { 
        dt.Rows[dt.Rows.Count - 1][i] = GetCellValue(doc, cell); 
        i++; 
       } 
      } 
     } 

    } 
    return dt; 
} 

private string GetCellValue(SpreadsheetDocument doc, Cell cell) 
{ 
    string value = cell.CellValue.InnerText; 
    if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString) 
    { 
     return doc.WorkbookPart.SharedStringTablePart.SharedStringTable.ChildElements.GetItem(int.Parse(value)).InnerText; 
    } 
    return value; 
} 
} 

Как использовать:

new OpenXmlExcel().ExcelToCsv("f1.xlsx","f1.csv",";",true); 
or 
//use default: separator=";" ,first row is header 
new OpenXmlExcel().ExcelToCsv("f1.xlsx","f1.csv"); 
+0

Я ищу решение OpenXML. Благодаря! – user793468

+0

Он добавляет разделитель в конце каждой строки. Любые предложения по обработке этого? – user793468

+0

код должен означать, что символ NEWLINE является концом строки. Вам нужен этот разделитель. –