2012-10-04 44 views
0

我需要读取excel文档并将单元格中包含的数据放在数据库中。但是,我注意到的问题是,当我从行中读取数据时,它们不会按照它们在表单中出现的顺序出现。我该如何解决这个问题?使用OPENXML读取Excel电子表格行单元时出现问题

public void getrowdata(){ 

IEnumerable<Row> dataRows = from row in s.worksheetpart.Worksheet.Descendants<Row>() 
               where row.RowIndex > 6 
               select row; 

// extract the data in the row in order 
       foreach (Row row in dataRows) 
       { 
        var cellValues = from cell in row.Descendants<Cell>() 
            select ((cell.CellValue != null && cell.DataType != null && cell.DataType.HasValue) 
             && (sharedString.HasChildren && int.Parse(cell.CellValue.InnerText) < sharedString.ChildElements.Count) 
             ? sharedString.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText 
             : ((cell.CellValue != null && cell.CellValue.InnerText != null) ? cell.CellValue.InnerText : String.Empty)); 


//--cellValues.toArray() and then access each cell via index in array 


} 

    public void ReadDSheetsToBuffer() 
     { 
      try 
      { 
       //Open the Excel workbook. 
       using (SpreadsheetDocument document = SpreadsheetDocument.Open(file.FullName, true)) 
       { 
        //References to the workbook and Shared String Table. 
        workBook = document.WorkbookPart.Workbook; 
        workSheets = workBook.Descendants<Sheet>(); 
        sharedStrings = document.WorkbookPart.SharedStringTablePart.SharedStringTable; 
        ExtractSheetstoMemory2(document); 

       } 
      } 
      catch (Exception ex) 
      { 
       throw ex.GetBaseException(); 
      } 
     } 

示例文件发现在Sample Excel File I read with the code

,下面将我访问存储了在该行中的单元格的值的方式类型。 。 。

if (values[228] != null) 
       itemdetail.Custom1 = rowvalues[228].Trim(); 
      if (values[229] != null) 
       itemdetail.Custom2 = rowvalues[229].Trim(); 
      if (values[230] != null) 
       itemdetail.Custom3 = rowvalues[230].Trim(); 
      if (values[231] != null) 
       itemdetail.Custom4 = rowvalues[231].Trim(); 
      if (values[232] != null) 
       itemdetail.Custom5 = rowvalues[232].Trim(); 
      if (values[233] != null) 
       itemdetail.Custom6 = rowvalues[233].Trim(); 

我在使用单元格引用接入小区的innerText

foreach (Row row in dataRows) 
       { 
        if (row.RowIndex > 6) 
        { 

         String theCell = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(1) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell2 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(2) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell3 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(3) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell4 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(4) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell5 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(5) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell6 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(6) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell7 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(7) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell8 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(8) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell9 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(9) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell10 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(10) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell11 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(11) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell112 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(12) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell13 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(13) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell14 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(14) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 
         String theCell15 = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(15) + row.RowIndex.ToString()).FirstOrDefault().InnerText; 

} 
} 
+0

你能上传一个例子Excel文件的功能?所以我会看看它。 – Hans

+0

我已将文件上传到http://www.filedropper.com/dcttestdata – Kobojunkie

+0

行号是“x:row”元素的“r”属性。您可能必须使用它来将它们映射回适当的位置,而不是假定它们正在使用存储顺序来隐式定位它们。 – RBarryYoung

回答

0

你需要看看CellReference财产(这是在XML文件中的细胞r属性)尝试为你迭代单个单元格。这包含A1格式的单元格地址,其中A是列,1是行。

例如行68上的列233将是HY68。您可能会发现this question对于如何生成列字母很有用。然后,您可以检查CellReference为这是你检查该行的后代每个细胞,提取列字母和使用switch语句来填充你的ItemDetail

唯一明显的方式相关的部分,我可以看到,以避免迭代单个单元格可能是使用XPath直接从底层XML/.xslx文件中提取它们。不知道如何在C#中使用SpreadsheetDocument对象及其后代。

你也可以为了通过CellReference财产现有的查询,这将让细胞为了之一,但可能会导致空单元格的问题(即返回可能无法从第10列的单元格第10电池)


编辑:处理丢失的单元格/ null引用只需要您在访问.InnerText属性之前检查引用。

Cell theCell = row.Descendants<Cell>().Where(c => c.CellReference == ExcelColumnFromNumber(1) + row.RowIndex.ToString()).FirstOrDefault(); 

String theCellValue = ""; 

if (theCell != null) 
{ 
    theCellValue = theCell.InnerText; 
} 

它可能是整洁来包装很多,是以Cell作为参数,并返回一个String要么含有InnerText或空字符串

+0

我尝试通过cellreference访问,但它似乎当它击中“失踪”单元格时,它会引发'空引用'异常。而且我至少注意到它发生在我的一些行(不是全部)的G列上。所以通过单元格引用访问似乎是一个困难的方法,或者你有一定的方式应该完成?请看我的例子。 – Kobojunkie

+0

用处理空引用的方式更新了答案 – barrowc

相关问题