Autor Beitrag
WSS-130
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mi 16.01.13 11:27 
Hallo Zusammen,

erstmal hoffe ich, dass meine frage in diesem bereich richtig gestellt ist.

Nun zur Frage:
Ich erstelle mit meinem Programm eine Liste deren Einträge wieder eine Liste ist:
--> Liste Container hat 10000 Elemente, jedes Element hat 10 Elemente.

Die "unteren" Elemente stehen in einer extra Klasse und können über get-Methoden ausgelesen werden.
Im großen und ganzen ist mein Container ein dynamisches, 2 dimensionales Array.

Zur Ausgabe des Ergebnisses soll die Liste in eine xls exportiert werden. Und ich habe leider noch keine richtige Idee wie ich das anfangen kann.
Hat mir da jemand eine Idee :-) ?
Was bereits funktioniert ist der Export als CSV, den ich dann ja auch mit Excel öffnen kann. Allerdings sollen noch zusätzliche Infos ausgegeben werden und da kommt Excel ins Spiel....
Macht es Sinn StreamWriter des csv-exports zu benutzen um den Excel-Export zu erstellen?

Meinen Code für den csv Export habe ich mal angehängt, vll hilft der ja weiter:
ausblenden csv-Export
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
string sep = ";";

using (StreamWriter sw = File.CreateText(path))
{
   foreach (var item in container)
   {
       string value = null, fct = null, incr = null;

       foreach (var function in item.getFunction)
       {
           value = function[0];
           fct = function[1];
           incr = function[2];
           break;
       }
       sw.WriteLine(item.getNameInt + sep
                      + item.getName + sep
                      + item.getDek + sep
                      + item.getLok + sep
                      + item.getRef + sep
                      + item.getRW + sep
                      + item.getSign + sep
                      + item.getSNA + sep
                      + item.getLength + sep
                      + value + sep
                      + fct + sep
                      + incr);
   }
}


Hoffe ihr helft mir eine schöne Lösung für mein Problem zu finden :-)

Gruß
Markus
WSS-130 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mi 16.01.13 16:37 
Ich habe jetzt mal eine Lösung gefunden... allerdings ist die sehr sehr langsam. der Export braucht im Vergleich zur csv Version die ca 20-fache Zeit.

Den Code hab ich angehängt... gibt es hier was zu verbessern? Oder liegt as rein an der COM Schnittstelle?

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
public void exportXLS(List<signFlow> container)
        {
            //Variablen
            string colLast = "L";
            int rowCurrent = 1;
            object n = System.Reflection.Missing.Value;

            //start excel
            Excel.Application excapp = new Excel.Application();
            //excapp.Visible = true;
            var workbook = excapp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
            var sheet = (Excel.Worksheet)workbook.Sheets[1]; //indexing starts from 1

            //Excel befüllen
            foreach (signFlow flow in container)
            {
                int colCurrent = 1;

                sheet.Cells[rowCurrent, colCurrent] = flow.getName;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getDek;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getLok;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getRef;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getRW;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getSign;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getSNA;
                colCurrent++;
                sheet.Cells[rowCurrent, colCurrent] = flow.getLength;
                colCurrent++;
                if (flow.getFunction.Count >= 1)
                {
                    foreach (string[] function in flow.getFunction)
                    {
                        sheet.Cells[rowCurrent, colCurrent] = value;
                        colCurrent++;
                        sheet.Cells[rowCurrent, colCurrent] = fct;
                        colCurrent++;
                        sheet.Cells[rowCurrent, colCurrent] = incr;
                        colCurrent++;
                        if (flow.getFunction.Count > 1)
                            rowCurrent++;
                        colCurrent -= 3;
                    }
                }
                rowCurrent++;
            }

            // Excel formatieren
            // Schriftart
            sheet.get_Range("A1", colLast + rowCurrent).Font.Name = "Arial Narrow";
            // Schriftgröße
            sheet.get_Range("A1", colLast + rowCurrent).Font.Size = 8;
            // Fettschrift
            sheet.get_Range("A1", colLast + "1").Font.Bold = true;
            // Orientierung aufwärts
            sheet.get_Range("M1""U1").Orientation = Excel.XlOrientation.xlUpward;
            // Ausrichtung linksbündig
            sheet.get_Range("A1", colLast + "1").HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;
            // Spaltenbreite
            sheet.get_Range("A1""A1").ColumnWidth = 20;
            sheet.get_Range("B1""B1").ColumnWidth = 20;
            sheet.get_Range("C1""C1").ColumnWidth = 13;
            sheet.get_Range("D1""D1").ColumnWidth = 12;
            sheet.get_Range("E1""E1").ColumnWidth = 20;
            sheet.get_Range("F1""F1").ColumnWidth = 20;
            sheet.get_Range("G1""G1").ColumnWidth = 8;
            sheet.get_Range("H1""H1").ColumnWidth = 8;
            sheet.get_Range("I1""I1").ColumnWidth = 14;
            sheet.get_Range("J1""J1").ColumnWidth = 6;
            sheet.get_Range("K1""K1").ColumnWidth = 15;
            sheet.get_Range("L1""L1").ColumnWidth = 30;
            // Zeilenumbruch
            sheet.get_Range("A1", colLast + rowCurrent).Cells.WrapText = true;
            // Autofilter
            sheet.get_Range("A1", colLast + rowCurrent).AutoFilter(1, Type.Missing, Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);    // rowCurrent - 1, wenn %Ende% entfällt
            // Fenster fixieren
            Excel.Range firstRow = sheet.get_Range("B2""B2");
            firstRow.Activate();
            firstRow.Select();
            firstRow.Application.ActiveWindow.FreezePanes = true;

            //Datei speichern und workbook schließen
            workbook.SaveAs("D:\\Markus_Ehinger\\C#-Versuche\\Files einlesen\\klasse_zu_xls\\ConsoleApplication1\\Exports\\export.xls", n, n,
                    n, n, n, Excel.XlSaveAsAccessMode.xlNoChange,
                    n, n, n, n, n);
            workbook.Close(false, n, n);

            //Variablen auf Null setzen
            sheet = null;
            workbook = null;
        }
    
    }


Viele Grüße
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Mi 16.01.13 23:08 
Hallo,

in meinen Augen "the one and only": www.carlosag.net/tools/excelxmlwriter/

Es gibt sogar einen Codegenerator, der dir den passenden Code für eine vorhandene Excel Tabelle ausgibt. Funktioniert auch auf PCs ohne Office und ist zudem sau schnell.

_________________
Gruß
Christoph
WSS-130 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 17.01.13 10:37 
Hallo Christoph,

danke für den Link..Ich kann allerdings im moment nichts damit anfangen. Wie kann ich den excelxmlwriter nun in mein Projekt importieren.
Der Code Generator funktiniert nicht. Er stürzt sofort ab...(Keine Rückmeldung)

hat sich bereits jemand Code erzeugt?

Edit:
Okay ich konnte Code erzeugen... Der muss jetzt noch etwas angepasst werden aber sonst passt das....

Allerdings kann ich nicht kompilieren... habe nach dem Versuch 3 Fehlermeldungen:
- ..."CarlosAG" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)
- ..."WorksheetStyleCollection" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)
- ..."WorksheetCollection" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)

Die Using-Direktive habe ich natürlich angegeben:
ausblenden C#-Quelltext
1:
using CarlosAg.ExcelXmlWriter;					

Und die beiden dll's
- CarlosAg.ExcelXmlWriter.dll
- CarlosAg.Utils.dll
habe ich dem Projekt hinzugefügt


Übersehe ich etwas? Nein, oder?
Arbeite mit VS C#2010 Express

Grüße
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Do 17.01.13 17:50 
Gibt es auf der Seite kein Beispiel Projekt? Eigentlich sollte es laufen. Ist sicher nur eine Kleinigkeit!

_________________
Gruß
Christoph
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 17.01.13 18:22 
Der Code scheint älter zu sein. Mischt du vielleicht .Net 4 mit .Net 2 Code?
WSS-130 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Di 22.01.13 17:34 
Ich weiß es nicht, ich denke nicht.

Habe es jetzt aber mal so gelassen. Schließlich funktioniert die csv ausgabe so wie ich will und sehr sehr schnell.
Filter und das Layout muss man dann halt noch von Hand in Excel Hinzufügen und die datei dann als xls speichern. Das ist zwar nicht schön, aber für die ersten Tests tut es.
Der xls export klappt ja auch, ist halt extrem langsam....gibts da außer dem CarlosAG.XMLWirter noch andere Lösungen oder Ideen?

Gruße
Markus
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Di 22.01.13 19:33 
Keine Ahnung warum du das nicht zum Laufen bringen kannst!? Ich habe es gerade mit 4.0 in <1min geschafft.

Zitat:
danke für den Link..Ich kann allerdings im moment nichts damit anfangen. Wie kann ich den excelxmlwriter nun in mein Projekt importieren.
Der Code Generator funktiniert nicht. Er stürzt sofort ab...(Keine Rückmeldung)


Ich denke dir fehlen die Grundlagen wie man eine .Net DLL verwendet, oder?

_________________
Gruß
Christoph
WSS-130 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mi 23.01.13 09:58 
Ja ich hab das bisher nochnie gemacht.

Ich habe versucht die .dll über using einzubinden und dann den aus dem "Code-Generator" generierten Code über eine Methode eingebunden.
Wie gesagt, Problem war immer, dass die CarlosAg.ExcelXmlWriter.dll nicht im Projekt gefunden wurde???
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 23.01.13 10:28 
Zitat:
Ich habe versucht die .dll über using einzubinden


Du hast die falsche Vorstellung was using macht. Using bindet nichts ein. Using ist eine Art Bekanntmachung von Namespaces damit man nicht immer jede Klasse mit ihrem vollen Namen schreiben muss (also Namespace.Klasse) sondern einfach den Klassennamen nehmen kann wenn man den Namespace per using bekanntgemacht hat. Man kann auch vollständig ohne using auskommen.

Eine Assembly die du benutzen willst mußt du im Projekt explizit referenzieren. Den entsprechenden Menüpunkt solltest du im Solutionexplorer finden wenn du dort auf dem Projekt mal das Kontextmenü öffnest.