zapisanie DataTable do Excela

0

Witam!
Trochę już szukałem, jednak nic konkretnego nie znalazłem, więc pytanie:

 DataTable dt ;//zapełnią danymi z zapytania sql

Teraz po kliknięciu export chciałbym zapisać table do exela, doszedłem do:

saveFileDialog2.Filter = "Skoroszyt programu Microsoft Office Excel |*.xls";
saveFileDialog2.Title = "Zapisz do Microsoft Office Excel - plik xls";
saveFileDialog2.FileName = nazwa + ".xls";
if (saveFileDialog2.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
       string path = saveFileDialog2.FileName;         
}

Czy ktoś ma może jakąś funkcję która mi pomoże?:)

1

A musi być koniecznie prehistoryczny xls? Bo jeśli możesz używać "nowego" standardu, to pomocna może być np. taka biblioteka: http://epplus.codeplex.com/.

0

Dziękuje za odpowiedź, jednak wymagają ode mnie również współpracy z office'm 2003? Więc czekam na dalsze propozycje;)

1

Tutaj wszystko jest fajnie opisane oraz jest przykładowy kod.

http://stackoverflow.com/questions/151005/create-excel-xls-and-xlsx-file-from-c-sharp

1

Kiedyś (jakieś sto lat temu) stosowałem taką sztuczkę, że zapisywałem xls jako ... HTML. Dawałem <TABLE>, <TR>, <TD> ... i zapisywałem z rozszerzeniem xls. Rozróżnia TD od TH, poprawnie interpretuje niektóre style i colspan, rowspan... Łykał to jak młody pelikan... Tylko dopiero 2007 się obraził... (ale szczegółów nie pomnę)

0

Również dziękuje za odpowiedź, jednak przy otwieraniu pliku za pomocą excela 2003 wyskakuje:
<image = "http://4programmers.net/Forum/C_i_.NET/142533-zapisanie_datatable_do_excela?mode=download&id=3917
">http://4programmers.net/Forum/C_i_.NET/142533-zapisanie_datatable_do_excela?mode=download&id=3917</image>
Po kliknięciu ok:
user image
Po kliknięciu tak:
user image
Później po odpaleniu pliku jak się zapisze wszystko ładnie śmiga. Dla porównania oczywiście nowszy office w ogóle nie odpala pliku...
Kod:

        private void zapis_scv(DataTable dt, OleDbDataAdapter DataAdapter)
        {
            DataSet ds = new DataSet("New_DataSet");
            string nazwa = dt.Rows[0][1].ToString() +"_"+ dt.Rows[0][2].ToString();
            string nazwa2 = "";
            foreach (char x in nazwa)
            {
                if (x == ' ' || x == '/' || x == '\\' || x == '?' || x == '*' || x == '"' || x == '<' || x == '>' || x == '|' || x == ':')
                {
                    nazwa2 = nazwa2 + "_";
                }
                else
                {
                    nazwa2 = nazwa2 + x;
                }
            }
            nazwa = nazwa2;
            dt.Columns.Remove("a");
            ds.Tables.Clear();
            ds.Tables.Add(dt);

            if (checkBox2.Checked == true) // scv - CSV
            {
                saveFileDialog1.Filter = "CSV |*.csv";
                saveFileDialog1.Title = "Zapisz do pliku CSV";
                saveFileDialog1.FileName = nazwa+".csv";
                if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                        string path = saveFileDialog1.FileName;
                        StreamWriter sw = new StreamWriter(path,false,Encoding.UTF8);
                        sw.Write(ToCsv(dt));
                        sw.Dispose();
                } 
            }
            if (checkBox1.Checked == true) //excel
            {
                
                saveFileDialog2.Filter = "Skoroszyt programu Microsoft Office Excel |*.xls";
                saveFileDialog2.Title = "Zapisz do Microsoft Office Excel - plik xls";
                saveFileDialog2.FileName = nazwa + ".xls";
                
                if (saveFileDialog2.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string path = saveFileDialog2.FileName;
                    ExcelLibrary.DataSetHelper.CreateWorkbook(path, ds);
                    saveFileDialog2.Dispose();                  
                }
            }

Jakieś propozycje?

1

http://code.google.com/p/excellibrary/issues/detail?id=54

As commented by [email protected], there's no error if file size exceeds about 6000 bytes. So I found this "solution": when I create my workbook, I fill 200 cells of the first sheet with null values to reach this size.

for (var k = 0; k < 200; k++)
workbook.Worksheets[0].Cells[k, 0] = new Cell(null);

dość kiepskie rozwiązanie ale zawsze coś na początek.

0

doceniam czas i chęć przedmówcy do pomocy, jednak niestety nie o to chodziło, ponieważ jest to rozwiązanie tymczasowe.
Bardziej szukam odpowiedzi na pytania:

  1. skąd błąd i jak się go pozbyć w bardziej przystępny sposób?
  2. dlaczego wygenerowany plik nie działa na nowszym excelu?
  3. Ewentualnie może inne rozwiązanie zrobienia z datatable pliku xls?
1

ech, coś spieprzyłeś...
Sprawdziłem przed chwilą. Mam Excela 2003 (11.5612.5606) Small Business Edition.
i taki plik: (zawartość)

<table>
	<tr>
		<th>Pierwszy rekord</th>
		<th>Druga komórka</th>
	</tr>
	<tr>
		<td>drugi wiersz</td>
		<td>2.2</td>
	</tr>
	<tr>
		<td colspan="2">połączone</td>
	</tr>
	<tr>
		<td rowspan="2">w pionie</td>
	</tr>
	<tr>
		<td>połączone</td>
	</tr>
</table>

(276 bajtów, 19 linii)
zapisane jako cos.xls
Otwiera bez problemu - zarówno jako dwuklik, jak i z poziomu Otwórz Excela.

0

Yyy.. to że spieprzyłem to ja nie wątpię :P
u mnie również działa to co napisałeś, jednak kod który generuje ww kod już nie;|
A może ta biblioteka być trefna? XD
Jednak dobry pomysł i spróbuje zaraz przerobić dataTable na html i zapisać do pliku;) Napisze jak skończę;)

Edit:
Jak to dobrze trafić na mądrzejszego od siebie ;)
Pozwolę sobie wkleić dla potomnych:

public static string ConvertDataTableToHtml(DataTable targetTable)
        {
            string htmlString = "";

            if (targetTable == null)
            {
                throw new System.ArgumentNullException("targetTable");
            }

            StringBuilder htmlBuilder = new StringBuilder();

            //Create Top Portion of HTML Document
            htmlBuilder.Append("<table border='1px' cellpadding='5' cellspacing='0' ");
            htmlBuilder.Append("style='border: solid 1px Black; font-size: small;'>");

            //Create Header Row
            htmlBuilder.Append("<tr align='left' valign='top'>");

            foreach (DataColumn targetColumn in targetTable.Columns)
            {
                htmlBuilder.Append("<td align='left' valign='top'>");
                htmlBuilder.Append(targetColumn.ColumnName);
                htmlBuilder.Append("</td>");
            }

            htmlBuilder.Append("</tr>");

            //Create Data Rows
            foreach (DataRow myRow in targetTable.Rows)
            {
                htmlBuilder.Append("<tr align='left' valign='top'>");

                foreach (DataColumn targetColumn in targetTable.Columns)
                {
                    htmlBuilder.Append("<td align='left' valign='top'>");
                    htmlBuilder.Append(myRow[targetColumn.ColumnName].ToString());
                    htmlBuilder.Append("</td>");
                }

                htmlBuilder.Append("</tr>");
            }

            //Create Bottom Portion of HTML Document
            htmlBuilder.Append("</table>");

            //Create String to be Returned
            htmlString = htmlBuilder.ToString();

            return htmlString;
        }

I oczywiście wywołanie:

                saveFileDialog2.Filter = "Skoroszyt programu Microsoft Office Excel |*.xls";
                saveFileDialog2.Title = "Zapisz do Microsoft Office Excel - plik xls";
                saveFileDialog2.FileName = nazwa + ".xls";
                
                if (saveFileDialog2.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string path = saveFileDialog2.FileName;
                    //Excel.Workbook book = new Excel.Workbook();
                    //Excel.Worksheet worksheet = new Excel.Worksheet();
                    //book.Worksheets.Add(worksheet);
                    //ExcelLibrary.DataSetHelper.CreateWorkbook(path, ds);
                    // double test = Convert.ToDouble(path.Length);
                    // label12.Text = test.ToString();
                    //saveFileDialog2.Dispose();
                    StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8);
                    sw.Write(ConvertDataTableToHtml(dt));
                    sw.Dispose();


A powiedzcie mi proszę czy ktoś z was kojarzy jak by to zrobić żeby w całym pliku były defoultowe ustawienia wyglądu, bo ustawiłem tymczasowe:

            htmlBuilder.Append("<table border='1px' cellpadding='5' cellspacing='0' ");
            htmlBuilder.Append("style='border: solid 1px Black; font-size: small;'>"); 

jednak wolał bym chyba mieć te ustawienia które excel daje podstawowe ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1