Laden...

Datagridview als Tabelle in Word speichern

Erstellt von shadow01 vor einem Jahr Letzter Beitrag vor einem Jahr 1.035 Views
S
shadow01 Themenstarter:in
2 Beiträge seit 2022
vor einem Jahr
Datagridview als Tabelle in Word speichern

Hallo Zusammen

Ich bin Frank und habe längere Zeit nicht mehr viel programmiert. Bevor ich nun auf CSharp umgestiegen bin habe ich lange vb.net programmiert.

Ich möchte für mich als Übung aus einer Form wo ich Name, Adresse, Offerte und in einem DataGridView Materialien (Position, Anzahl, Kurztext, Preis) eingeben kann ein Word erzeugen. Das Word wird aus einer Vorlagendatei erzeugt welche ich im Anhang angehäng habe. Die Datei heisst normalerweise Vorlage.docx leoder kann ich diese aber nicht hochladen so dass ich sie in ein PDF umwandeln musste.

Bis auf das DataGridView funktioniert dies auch ohne Probleme. Nun wollte ich euch fragen ob mir jemand helfen kann, wie ich das DGV in das Word bringe an vorgegebener stelle?



private void CreateWordDocument(object filename, object SaveAs)
        {
            Word.Application wordApp = new Word.Application();
            object missing = Missing.Value;
            Word.Document myWordDoc = null;

            if (File.Exists((string)filename))
            {
                object readOnly = false;
                object isVisible = false;
                wordApp.Visible = false;

                myWordDoc = wordApp.Documents.Open(ref filename, ref missing, ref readOnly,
                    ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing);
                myWordDoc.Activate();

                string Anschrift = BriefAnschrift(textBox1.Text, comboBox1.Text);

                //find and replace
                this.FindAndReplaceInWordTemplate(wordApp, "<Anschrift>", Anschrift);
                this.FindAndReplaceInWordTemplate(wordApp, "<Datum>", dateTimePicker1.Text);
                this.FindAndReplaceInWordTemplate(wordApp, "<Adresse>", CreateAdress(textBox2.Text, textBox7.Text, textBox3.Text, textBox4.Text, textBox5.Text));
                this.FindAndReplaceInWordTemplate(wordApp, "<Betreff>", textBox6.Text);
                this.FindAndReplaceInWordTemplate(wordApp, "<Anrede>", BriefAnrede(textBox1.Text, comboBox1.Text, textBox7.Text));
                this.FindAndReplaceInWordTemplate(wordApp, "<Offertentext>", textBox8.Text);

                //*************************************************
                //***           DGV in Word einfügen            ***
                //*************************************************


                if (dataGridView1.Rows.Count != 0)
                {
                    int RowCount = dataGridView1.Rows.Count;
                    int ColumnCount = dataGridView1.Columns.Count;
                    Object[,] DataArray = new object[RowCount + 1, ColumnCount + 1];

                    //add rows
                    int r = 0;
                    for (int c = 0; c <= ColumnCount - 1; c++)
                    {
                        for (r = 0; r <= RowCount - 1; r++)
                        {
                            DataArray[r, c] = dataGridView1.Rows[r].Cells[c].Value;
                            //this.FindAndReplaceInWordTemplate(wordApp, "<Material>", dataGridView1.Rows[r].Cells[c].Value);
                        } //end row loop
                    } //end column loop

                    Word.Document oDoc = new Word.Document();
                    oDoc.Application.Visible = true;

                    ////page orintation
                    //oDoc.PageSetup.Orientation = Word.WdOrientation.wdOrientLandscape;


                    dynamic oRange = oDoc.Content.Application.Selection.Range;
                    string oTemp = "";
                    for (r = 0; r <= RowCount - 1; r++)
                    {
                        for (int c = 0; c <= ColumnCount - 1; c++)
                        {
                            oTemp = oTemp + DataArray[r, c] + "\t";

                        }
                    }

                    //table format
                    oRange.Text = oTemp;

                    object Separator = Word.WdTableFieldSeparator.wdSeparateByTabs;
                    object ApplyBorders = true;
                    object AutoFit = true;
                    object AutoFitBehavior = Word.WdAutoFitBehavior.wdAutoFitContent;

                    oRange.ConvertToTable(ref Separator, ref RowCount, ref ColumnCount,
                                          Type.Missing, Type.Missing, ref ApplyBorders,
                                          Type.Missing, Type.Missing, Type.Missing,
                                          Type.Missing, Type.Missing, Type.Missing,
                                          Type.Missing, ref AutoFit, ref AutoFitBehavior, Type.Missing);

                    oRange.Select();

                    oDoc.Application.Selection.Tables[1].Select();
                    oDoc.Application.Selection.Tables[1].Rows.AllowBreakAcrossPages = 0;
                    oDoc.Application.Selection.Tables[1].Rows.Alignment = 0;
                    oDoc.Application.Selection.Tables[1].Rows[1].Select();
                    oDoc.Application.Selection.InsertRowsAbove(1);
                    oDoc.Application.Selection.Tables[1].Rows[1].Select();

                    //header row style
                    oDoc.Application.Selection.Tables[1].Rows[1].Range.Bold = 1;
                    oDoc.Application.Selection.Tables[1].Rows[1].Range.Font.Name = "Tahoma";
                    oDoc.Application.Selection.Tables[1].Rows[1].Range.Font.Size = 14;

                    //add header row manually
                    for (int c = 0; c <= ColumnCount - 1; c++)
                    {
                        oDoc.Application.Selection.Tables[1].Cell(1, c + 1).Range.Text = dataGridView1.Columns[c].HeaderText;
                    }

                    //table style 
                    oDoc.Application.Selection.Tables[1].set_Style("Grid Table 4 - Accent 5");
                    oDoc.Application.Selection.Tables[1].Rows[1].Select();
                    oDoc.Application.Selection.Cells.VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;

                    //header text
                    foreach (Word.Section section in oDoc.Application.ActiveDocument.Sections)
                    {
                        Word.Range headerRange = section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
                        headerRange.Fields.Add(headerRange, Word.WdFieldType.wdFieldPage);
                        headerRange.Text = "your header text";
                        headerRange.Font.Size = 16;
                        headerRange.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    }

                }
                //this.FindAndReplaceInWordTemplate(wordApp, "<Material>", dataGridView1.text);


                //*************************************
                //***           Fertig DGV          ***
                //*************************************

            }
            else
            {
                MessageBox.Show("File not Found!");
            }

            //Save as
            myWordDoc.SaveAs2(ref SaveAs, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing);
            myWordDoc.Close();
            wordApp.Quit();
            MessageBox.Show("File erstellt!");
        }

Gruss und Danke

16.835 Beiträge seit 2008
vor einem Jahr

Da es eine Übung für Dich ist als Hinweis: würde man so heutzutage gar nicht mehr machen.
Word Interop ist eine sehr alte / veraltete Technik und seit >10 Jahren gibt es für solche Wünsche OpenXML.
Welcome to the Open XML SDK 2.5 for Office

F
10.010 Beiträge seit 2004
vor einem Jahr

Und die Daten haben auch nichts im DataGridView zu suchen, die gehören per DataBinding angebunden, wenn überhaupt.

S
shadow01 Themenstarter:in
2 Beiträge seit 2022
vor einem Jahr

Hallo zusammen danke für die Antworten

@Abt danke ich werde mein Projekt mal mit OpenXML versuchen zu realisieren.


var runProp = new RunProperties();
                var runFont = new RunFonts { Ascii = "Arial" };
                var size = new FontSize { Val = new StringValue("20") }; //wieso wird die grösse durch 2 geteilt
                
                runProp.Append(runFont);
                runProp.Append(size);
                run.PrependChild(runProp);

allerdings habe ich noch nicht begriffen warum die FontSize geteilt durch 2 ist, soll heissen wenn ich eine Schriftgösse von 10 will muss ich das Value auf 20 setzen.

@FZelle
also die Idee wäre ein dass in einem DGV aus einer Db Materialien aufgelistet sind wellche selektiert werden können und die Anzahl angegeben werden kann. Also vorschau in der Form soll dann dies in einem zweiten DGV abgebildet werden. Was findest du daran falsch?

Gruss und Danke euch

16.835 Beiträge seit 2008
vor einem Jahr

FZelle meint, dass man so nicht programmiert.

Ein DGV ist zur Darstellung von Daten da, nicht für das Halten von Daten.
Du verwendest es jedoch als Datenquelle.

Besser wäre DataBinding: Du hast einen Punkt, wo Daten liegen.
Und diese Daten nimmst Du dann für die jeweiligen Aufgaben: Darstellung, Export, Whatever..
Overview of Data Binding and Windows Forms - Windows Forms .NET

WinForms erlaubt ein Vorgehen, wie Du es machst, wobei auch hier schon Datenbindung der eben bessere Weg wäre.
Bei anderen, moderneren Wegen geht prinzipiell i.d.R. nur noch Datenbindung.

Zur FontSize Größe: einfach in die Dokumentation schauen und lesen. Dafür ist sie da 😉FontSize Class (DocumentFormat.OpenXml.Wordprocessing)

The font sizes specified by this element’s val attribute are expressed as half-point values.

2.921 Beiträge seit 2005
vor einem Jahr

Sehe ich genauso wie Fzelle und Abt.

Einziger Unterschied:

Falls Dir Open XML zu kompliziert werden sollte,
es kann alles, kann aber auch ziemlich komplex werden.

Dann kannst Du auch Closed XML (nicht Microsoft) verwenden.
Das ist IMHO viel einfacher zu benutzen, falls das, was Du oben beschreibst, alles ist was Du machen möchtest.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.