0

I was earlier successful at converting Excel to datatable, but now, I have weirdly formatted table, following picture will show excel table, and table that I want to achieve.

var workbook = Workbook.Load("file.xls");
var worksheet = workbook.Worksheets[0];
var cells = worksheet.Cells;
var dataTable = new DataTable("datatable");


for (int colIndex = cells.FirstColIndex; colIndex <= cells.LastColIndex; colIndex++)
{
    dataTable.Columns.Add(cells[0, colIndex].StringValue);
}

for (int rowIndex = cells.FirstRowIndex; rowIndex <= cells.LastRowIndex; rowIndex++)
{
    var values = new List<string>();
    foreach(var cell in cells.GetRow(rowIndex))
    {
        values.Add(cell.Value.StringValue);
    }

    dataTable.LoadDataRow(values.ToArray(), true);
}

This is the code. When I use this with mentioned .xls I'm getting "price: row shifted left. Example: https://i.stack.imgur.com/2jZQY.png So, any help about how to solve this is more than welcome. Thanks.

el ninho
  • 4,183
  • 15
  • 56
  • 77
  • 2
    when you debug this what is the integer position on colIndex sounds like you have a count off by 1 somewhere.. also on rowIndex are you sure that you are starting them at 0 or are you looking to start them based on the first rowIndex or colIndex that it finds also instead of LastColIndex can you somehow get at the column Count to make it more percise – MethodMan Jan 30 '12 at 14:20
  • row A is merged 2 by 2 cells. When I convert it this way to datatable, this double rows got unmerged, value goes to upper cell, and down cell is empty, so second row shifts left. I added example. – el ninho Jan 30 '12 at 14:28
  • Can you try something different ..I want to paste in and slightly have you change your code.. and each foreach loop I will have a comment to explain ok – MethodMan Jan 30 '12 at 14:34
  • I pasted in the code below but you will have to either pass in the DataTable dt to your method or Create it like I have shown below. try that.. also make sure that you loop thru to see what the double values are and if they truly get converted to String I would also wrap the code around a Try Catch so that you can trap for any Type Conversion errors.. – MethodMan Jan 30 '12 at 14:42
  • Thanks. I'll try. Just tell me what to add to "using". Thanks. – el ninho Jan 30 '12 at 14:45
  • your using should be the same using System.Reflection; using Microsoft.Office.Interop.Excel; – MethodMan Jan 30 '12 at 14:48

3 Answers3

1

Here is a reference link that someone had the same issue with and how to resolve the Issue

How To Resolve Exce.Interop Issue Culture Settings

The bug is that .NET checks that your thread (C# or VB code) localization is suitable to MS Excel localization you installed earlier, and if not it tells that the Microsoft.Office.Interop library is old or invalid. Your thread localization is derived from your computer regional settings (from the control panel --> regional and language)

Then there are two options to solve this problem: 1. To change your thread localization (by code) 2. Install language pack for your Office

The first solution goes like this:

using System.Threading;     // For setting the Localization of the thread to fit
using System.Globalization; // the of the MS Excel localization, because of the MS bug.

            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            excelFileName = System.IO.Path.Combine(excelPath, "Ziperty Buy Model for Web 11_11_2011.xlsm");
Community
  • 1
  • 1
MethodMan
  • 18,625
  • 6
  • 34
  • 52
0

You can retrieve it without opening it

use "Excel 12.0 Macro" instead of "Excel 12.0" only for xlsm file

HDR=YES means that your Excel table has header

 Dim myWorkBookPath AS String = "C:\test.xlsx"
    Dim mySheetName As String= "Sheet1"
    Dim myRangeAddress as String = "A1:K10"  'if you retrieve this by program, think to remove all $ signs . .Replace("$","")
         Dim myXlConnectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR=YES""", myWorkBookPath)
              Dim myXlConnection = New OleDb.OleDbConnection(myXlConnectionString)
              Dim sXlCommand As OleDbCommand = New OleDbCommand(String.Format("Select * FROM [{0}${1}]", mySheetName, myRangeAddress), myXlConnection)
              Dim dt = New Data.DataTable()
              Dim da = New OleDbDataAdapter(sXlCommand)
              myXlConnection.Open()
              da.Fill(dt)
              myXlConnection.Close()
              Return dt
ainasiart
  • 382
  • 2
  • 10
-1

put into your using at the top of the .cs file

using System.Reflection; 
using Microsoft.Office.Interop.Excel;

        // TO USE:
        // 1) include COM reference to Microsoft Excel Object library
        // add namespace...
        // 2) using Excel = Microsoft.Office.Interop.Excel;
        private static void Excel_FromDataTable(<strong class="highlight">DataTable</strong> dt)
        {
            // Create an Excel object and add workbook...
            Excel.ApplicationClass excel = new Excel.ApplicationClass();
            Excel.Workbook workbook = excel.Application.Workbooks.Add(true); // true for object template???

            // Add column headings...
            int iCol = 0;
            foreach (DataColumn c in dt.Columns)
            {
                iCol++;
                excel.Cells[1, iCol] = c.ColumnName;
            }
            // for each row of data...
            int iRow = 0;
            foreach (DataRow r in dt.Rows)
            {
                iRow++;

                // add each row's cell data...
                iCol = 0;
                foreach (DataColumn c in dt.Columns)
                {
                    iCol++;
                    excel.Cells[iRow + 1, iCol] = r[c.ColumnName];
                }
            }

            // Global missing reference for objects we are not defining...
            object missing = System.Reflection.Missing.Value;

            // If wanting to Save the workbook...
            workbook.SaveAs("TestExcel.xls",
                Excel.XlFileFormat.xlXMLSpreadsheet, missing, missing,
                false, false, Excel.XlSaveAsAccessMode.xlNoChange,
                missing, missing, missing, missing, missing);

            // If wanting to make Excel visible and activate the worksheet...
            excel.Visible = true;
            Excel.Worksheet worksheet = (Excel.Worksheet)excel.ActiveSheet;
            ((Excel._Worksheet)worksheet).Activate();

            // If wanting excel to shutdown...
            ((Excel._Application)excel).Quit();
        }
MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • I got exception "Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))" And you have declared iCol two times. – el ninho Jan 30 '12 at 15:02
  • Let me double check the code.. I hate editing here sometimes.. hold on – MethodMan Jan 30 '12 at 15:03
  • I pasted what I have and it works .. what line are you getting the error on.. this is what my Method looks like – MethodMan Jan 30 '12 at 15:06
  • Excel.Workbook workbook = excel.Application.Workbooks.Add(true); here I get exception. – el ninho Jan 30 '12 at 15:09
  • I think you may have a Culture issue look at this link.. this should resolve http://support.microsoft.com/default.aspx?scid=kb;en-us;320369 – MethodMan Jan 30 '12 at 15:11