Pereiti prie turinio

Excel XLS to XML konvertavimas (dviejų lentelių) su OPENXML


Rekomenduojami pranešimai

Sveiki. Turiu Windows Form'ą, kurtą su Visual Studio C# programavimo kalba. Užduotis tokia, kad man reikia, kad iš Excel SpreadSheet, kuriame yra DVI LENTELĖS, šį failą (.XLS) konvertuoti į XML failą (XLS to XML). Padariau programą, kad ji konvertuoti VIENĄ lentelę į XML (kas puikiai veikia), tačiau problema tame, kad su DVEJOMIS lentelėmis mano programa neveikia. Štai nuotrauka, kaip atrodo mano Excel SpreadSheet:

 

http://i.stack.imgur.com/hr3Mq.png

 

Kaip matote, yra tos dvi lentelės. Tačiau programa nuskaito tik pirmąją, ir po to išmeta klaidą ties 4 stulpeliu (kuris yra paskutinis stulpelis pirmoje lentelėje):

 

http://s4.postimg.org/kzh6tsjq5/Untitled.png

 

Mano pagrindinis programos failas (ConvertExcelToXML.cs):

 

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace CSOpenXmlExcelToXml
{
   public class ConvertExcelToXml
   {
       /// <summary>
       ///  Read Data from selected excel file into DataTable
       /// </summary>
       /// <param name="filename">Excel File Path</param>
       /// <returns></returns>
       private DataTable ReadExcelFile(string filename)
       {
           // Initialize an instance of DataTable
           DataTable dt = new DataTable();     

           try
           {
               // Use SpreadSheetDocument class of Open XML SDK to open excel file
               using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filename, false))
               {                   

                   // Get Workbook Part of Spread Sheet Document
                   WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;

                   // Get all sheets in spread sheet document 
                   IEnumerable<Sheet> sheetcollection = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();

                   // Get relationship Id
                   string relationshipId = sheetcollection.First().Id.Value;

                   // Get sheet1 Part of Spread Sheet Document
                   WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(relationshipId);

                   // Get Data in Excel file
                   SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
                   IEnumerable<Row> rowcollection = sheetData.Descendants<Row>();

                   // If there is no rows in the spreadsheet at all, when just return in how it is and output it
                   if (rowcollection.Count() == 0)
                   {
                       return dt;
                   }

                   // ============================================================================================================

                   // Add columns
                   foreach (Cell cell in rowcollection.ElementAt(0))
                   {
                       dt.Columns.Add(GetValueOfCell(spreadsheetDocument, cell));
                   }

                   // Add rows into DataTable
                   foreach (Row row in rowcollection)
                   {
                       // Create temporary row to read rows in spreadsheet
                       DataRow temprow = dt.NewRow();
                       int columnIndex = 0;
                       foreach (Cell cell in row.Descendants<Cell>())
                       {
                           // Get Cell Column Index
                           int cellColumnIndex = GetColumnIndex(GetColumnName(cell.CellReference));

                           if (columnIndex < cellColumnIndex)
                           {
                               do
                               {
                                   temprow[columnIndex] = string.Empty;
                                   columnIndex++;
                               }

                               while (columnIndex < cellColumnIndex);
                           }

                           temprow[columnIndex] = GetValueOfCell(spreadsheetDocument, cell);
                           columnIndex++;
                       }

                       // Add the row to DataTable
                       // the rows include header row
                       dt.Rows.Add(temprow);
                   }
               }

               // Here remove header row
               dt.Rows.RemoveAt(0);
               return dt;
           }

           // Throw error message
           catch (IOException ex)
           {
               throw new IOException(ex.Message);
           }
       }

       /// <summary>
       ///  Get Value of Cell
       /// </summary>
       /// <param name="spreadsheetdocument">SpreadSheet Document Object</param>
       /// <param name="cell">Cell Object</param>
       /// <returns>The Value in Cell</returns>
       private static string GetValueOfCell(SpreadsheetDocument spreadsheetdocument, Cell cell)
       {
           // Get value in Cell
           SharedStringTablePart sharedString = spreadsheetdocument.WorkbookPart.SharedStringTablePart;
           if (cell.CellValue == null)
           {
               return string.Empty;
           }

           string cellValue = cell.CellValue.InnerText;

           // The condition that the Cell DataType is SharedString
           if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
           {
               return sharedString.SharedStringTable.ChildElements[int.Parse(cellValue)].InnerText;
           }
           else
           {
               return cellValue;
           }
       }

       /// <summary>
       /// Get Column Name From given cell name
       /// </summary>
       /// <param name="cellReference">Cell Name(For example,A1)</param>
       /// <returns>Column Name(For example, A)</returns>
       private string GetColumnName(string cellReference)
       {
           // Create a regular expression to match the column name of cell
           Regex regex = new Regex("[A-Za-z]+");
           Match match = regex.Match(cellReference);
           return match.Value;
       }

       /// <summary>
       /// Get Index of Column from given column name
       /// </summary>
       /// <param name="columnName">Column Name(For Example,A or AA)</param>
       /// <returns>Column Index</returns>
       private int GetColumnIndex(string columnName)
       {
           int columnIndex = 0;
           int factor = 1;

           // From right to left
           for (int position = columnName.Length - 1; position >= 0; position--)   
           {
               // For letters
               if (Char.IsLetter(columnName[position]))
               {
                   columnIndex += factor * ((columnName[position] - 'A') + 1) - 1;
                   factor *= 26;
               }
           }

           return columnIndex;
       }

       /// <summary>
       /// Convert DataTable to Xml format
       /// </summary>
       /// <param name="filename">Excel File Path</param>
       /// <returns>Xml format string</returns>
       public string GetXML(string filename)
       {
           using (DataSet ds = new DataSet())
           {
               ds.DataSetName = "Document-Order";
               ds.Tables.Add(this.ReadExcelFile(filename));
               return ds.GetXml();
           }
       }
   }
}

 

Čia yra mano formos kodas (MainForm.cs):

 

using System;
using System.IO;
using System.Windows.Forms;

namespace CSOpenXmlExcelToXml
{
   public partial class MainForm : Form
   {
       public MainForm()
       {
           InitializeComponent();
           this.btnSaveAs.Enabled = false;
       }

       /// <summary>
       ///  Open an dialog to let users select Excel file
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void btnBrowser_Click(object sender, EventArgs e)
       {
           // Initializes a OpenFileDialog instance 
           using (OpenFileDialog openfileDialog = new OpenFileDialog())
           {
               openfileDialog.RestoreDirectory = true;
               openfileDialog.Filter = "Excel files(*.xlsx;*.xls)|*.xlsx;*.xls";

               if (openfileDialog.ShowDialog() == DialogResult.OK)
               {
                   tbExcelName.Text = openfileDialog.FileName;
               }
           }
       }

       /// <summary>
       ///  Convert Excel file to Xml format and view in Listbox control
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void btnConvert_Click(object sender, EventArgs e)
       {
           tbXmlView.Clear();
           string excelfileName = tbExcelName.Text;

           if (string.IsNullOrEmpty(excelfileName) || !File.Exists(excelfileName))
           {
               MessageBox.Show("The Excel file is invalid! Please select a valid file.");
               return;
           }

           try
           {
               string xmlFormatstring = new ConvertExcelToXml().GetXML(excelfileName);
               if (string.IsNullOrEmpty(xmlFormatstring))
               {
                   // Line just for checking, if Excel document is empty. If it's true, when just print out an error message
                   MessageBox.Show("The content of Excel file is Empty!");
                   return;
               }

               // Print it in TextView
               tbXmlView.Text = xmlFormatstring;

               // If txbXmlView has text, set btnSaveAs button to be enable
               btnSaveAs.Enabled = true;
           }
           catch (Exception ex)
           {
               // General error message checking for errors
               MessageBox.Show("Error occurs! The error message is: " +ex.Message);
           }
       }

       /// <summary>
       ///  Save the XMl format string as Xml file
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void btnSaveAs_Click(object sender, EventArgs e)
       {
           // Initializes a SaveFileDialog instance 
           using (SaveFileDialog savefiledialog = new SaveFileDialog())
           {
               savefiledialog.RestoreDirectory = true;
               savefiledialog.DefaultExt = "xml";
               savefiledialog.Filter = "All Files(*.xml)|*.xml";
               if (savefiledialog.ShowDialog() == DialogResult.OK)
               {
                   Stream filestream = savefiledialog.OpenFile();
                   StreamWriter streamwriter = new StreamWriter(filestream);
                   streamwriter.Write("<?xml version='1.0'?>" +
                       Environment.NewLine + tbXmlView.Text);
                   streamwriter.Close();
               }
           }
       }

       // Disable maximize button of the form
       private void MainForm_Load(object sender, EventArgs e)
       {
           this.MaximizeBox = false;                           //this is an instance of Form or its decendant
       }
   }
}

 

Taip pat padariau StackTrace ties 70 MainForm.cs eilute (

MessageBox.Show("Error occurs! The error message is: " +ex.Message);

):

 

http://s16.postimg.org/68u960mlx/Untitled.png

 

Ir CallStack (tos pačios eilutės):

 

http://s2.postimg.org/hsijkmnhl/Untitled.png

 

 

Pagal StackTrace informaciją sprendžiu, kad kažkas yra negerai pagrindinio failo 82 eilutėje (

temprow[columnIndex] = GetValueOfCell(spreadsheetDocument, cell);

).

 

Su šia problema "sėdžiu" jau gal savaitė, rašiau įvairiuose forumuose (nuo StackOverflow iki openxmldeveloper.org/), tačiau jokios konkrečios pagalbos taip ir nesulaukiau (vieni siūlo nenaudoti OpenXML biblioteką, tačiau bendros išvados nepriėjau).

 

Dėkui už bet kokią pagalbą. Nors daug vilčių kaip ir nebeteikiu šiam projektui (kaip bebūtų gaila, nes tai kaip ir mano praktikos įmonėje projektas), tačiau galbūt kam nors yra tekę susipažinti su tokiais dalykais ir pasidalins savąja patirtimi. Dėkui.

Redagavo MrDBVids
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

  • Prisijunk prie bendruomenės dabar!

    Uždarbis.lt nariai domisi verslo, IT ir asmeninio tobulėjimo temomis, kartu sprendžia problemas, dalinasi žiniomis ir idėjomis, sutinka būsimus verslo partnerius ir dalyvauja gyvuose susitikimuose.

    Užsiregistruok dabar ir galėsi:

    ✔️ Dalyvauti diskusijose;

    ✔️ Kurti naujas temas;

    ✔️ Rašyti atsakymus;

    ✔️ Vertinti kitų žmonių pranešimus;

    ✔️ Susisiekti su bet kuriuo nariu asmeniškai;

    ✔️ Naudotis tamsia dizaino versija;

    ir dar daugiau.

    Registracija trunka ~30 sek. ir yra visiškai nemokamai.

  • Karštos temos

×
×
  • Sukurti naują...