2017-01-05 2 views
0

Ich habe eine App erstellt, die mir hilft, die Spalten in einer Excel-Datei neu anzuordnen. Das Problem ist, dass die exportierte Datei genau wie die ursprüngliche Datei ist, wenn ich die Datei speichere, selbst wenn die Datagridansicht so ist, wie ich es möchte.Importieren Sie eine Excel-Datei, ordnen Sie das Spaltenlayout neu und exportieren Sie das neue Layout zurück nach Excel

Kann mir jemand sagen, wo ich falsch liege? Hier

ist der Code:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using Excel; 
using System.IO; 
using Microsoft.Office.Tools.Excel; 
using System.Data.SqlClient; 
using System.Configuration; 
namespace ReadExcelFiles 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     DataSet result; 
     private void btnOpen_Click(object sender, EventArgs e) 
     { 
      //========================================================== 
      //CODE FOR IMPORTING DATA TO DATAGRIDVIEW=================== 
      //========================================================== 
      using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "Excel Workbook|*.xls", ValidateNames = true }) 
      { 
       if (ofd.ShowDialog() == DialogResult.OK) 
       { 
        FileStream fs = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read); 
        IExcelDataReader reader = ExcelReaderFactory.CreateBinaryReader(fs); 
        reader.IsFirstRowAsColumnNames = true; 
        result = reader.AsDataSet(); 
        cboSheet.Items.Clear(); 
        foreach (DataTable dt in result.Tables) 
         cboSheet.Items.Add(dt.TableName); 
        reader.Close(); 
       } 
      } 
     } 

     private void cboSheet_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      //================================================ 
      //CODE FOR SHEET FILTER=========================== 
      //================================================ 
      dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex]; 
     } 

     private void btnArg_Click(object sender, EventArgs e) 
     { 
      //============================================== 
      //CODE FOR COLUMN SORTING ====================== 
      //============================================== 
      dataGridView.Columns["BUYER_NAME"].DisplayIndex = 0; 
      dataGridView.Columns["PO_NUMBER"].DisplayIndex = 1; 
      dataGridView.Columns["PO_LINE_NUMBER"].DisplayIndex = 2; 
      dataGridView.Columns["VENDOR_NAME"].DisplayIndex = 3; 
      dataGridView.Columns["INVOICE_NUM"].DisplayIndex = 4; 
      dataGridView.Columns["INVOICE_DATE"].DisplayIndex = 5; 
      dataGridView.Columns["HOLD_LOOKUP_CODE"].DisplayIndex = 6; 
      dataGridView.Columns["AGING_DAYS"].DisplayIndex = 7; 
      dataGridView.Columns["INVOICE_AMOUNT"].DisplayIndex = 8; 
      dataGridView.Columns["INVOICE_CURRENCY_CODE"].DisplayIndex = 9; 
      dataGridView.Columns["INVOICE_CREATION_DATE"].DisplayIndex = 10; 
      dataGridView.Columns["TERMS"].DisplayIndex = 11; 
      dataGridView.Columns["BASE_AMOUNT"].DisplayIndex = 12; 
      dataGridView.Columns["OU"].DisplayIndex = 13; 
      dataGridView.Columns["SOURCE"].DisplayIndex = 14; 
      dataGridView.Columns["STYLE_NAME"].DisplayIndex = 15; 
      dataGridView.Columns["INVOICE_ID"].DisplayIndex = 16; 
      dataGridView.Columns["HELD_BY"].DisplayIndex = 17; 
      dataGridView.Columns["FULL_NAME_HELD_BY"].DisplayIndex = 18; 
      dataGridView.Columns["CURRENT_MARKVIEW_OWNER"].DisplayIndex = 19; 
      dataGridView.Columns["BUYER_ORG"].DisplayIndex = 20; 
      dataGridView.Columns["LAST_UPDATED_BY"].DisplayIndex = 21; 
      dataGridView.Columns["FULL_NAME_LAST_UPDATED_BY"].DisplayIndex = 22; 
     } 

     private void btnSave_Click(object sender, EventArgs e) 
     { 
      //================================================ 
      //CODE TO EXPORT DATAGRID TO EXCEL======= ======== 
      //================================================  
      // Creating a Excel object. 
      Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application(); 
      Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing); 
      Microsoft.Office.Interop.Excel._Worksheet worksheet = null; 
      try 
      { 

       worksheet = workbook.ActiveSheet; 

       worksheet.Name = "ExportedFromDatGrid"; 

       int cellRowIndex = 1; 
       int cellColumnIndex = 1; 

       //Loop through each row and read value from each column. 
       for (int i = 0; i < dataGridView.Rows.Count - 1; i++) 
       { 
        for (int j = 0; j < dataGridView.Columns.Count; j++) 
        { 
         // Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check. 
         if (cellRowIndex == 1) 
         { 
          worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[j].HeaderText; 
         } 
         else 
         { 
          worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString(); 
         } 
         cellColumnIndex++; 
        } 
        cellColumnIndex = 1; 
        cellRowIndex++; 
       }  
       //Getting the location and file name of the excel to save from user. 
       SaveFileDialog saveDialog = new SaveFileDialog(); 
       saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; 
       saveDialog.FilterIndex = 2;  
       if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
       { 
        workbook.SaveAs(saveDialog.FileName); 
        MessageBox.Show("Export Successful"); 
       } 
      } 
      catch (System.Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      finally 
      { 
       excel.Quit(); 
       workbook = null; 
       excel = null; 
      } 
     } 
    } 
} 

Antwort

0

Es ist nicht ganz klar, was Sie hier andere zu erreichen, müssen als Spalten in einem Excel-Arbeitsblatt neu zu organisieren. Ich Frage, warum Sie zwei verschiedene Excel-Bibliotheken verwenden würden? Eine Drittpartei Lib, um die Excel-Datei zu öffnen und dann Interop verwenden, um die Datei zu speichern? Es ist wirklich irrelevant für Ihre Frage nur zu fragen.

Es scheint auch seltsam, dass Sie dafür eine DataGridView vorstellen würden. Wenn Sie Spalten in einem Excel-Arbeitsblatt in eine neue Excel-Datei umordnen möchten, öffnen Sie einfach die Excel-Quelldatei, erstellen Sie eine neue Excel-Datei und kopieren Sie die Spalten nach Belieben. Es scheint unnötig, die DataGridView in dieses Bild einzuführen.

Wenn Sie die Daten in einem DataGridView haben, um brauchen die Spalten neu zu ordnen (wie Sie), dann müssen Sie sich bewusst sein, was passiert, wenn man eine DataGridView ‚s eingestellt DataSource. Wenn Sie die folgende Zeile verwenden:

dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex]; 

oberhalb der Linie setzt der DataGridView ‚s Datenquelle der Tabelle im Kombinationsfeld ausgewählt. Wenn eine DataGridView an eine DataTable gebunden ist, sind die eigentlichen Zellen in der DataGridView nicht wirklich zugänglich, wie Sie denken würden. Wenn Sie die Spalten der DataGridView (wie ich annehme Sie sind mit der btnArg_Click Ereignis) neu anordnen die Spalten in der DataGridView geändert werden, aber das gleiche gilt nicht für die Datentabelle, die das Gitter gebunden ist ... es ändert sich nicht . Also, wenn Sie eine Schleife durch die DataGridView und jede Zelle Adresse wie folgt: ...

worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString(); 

Dies wird i und j auf die Datentabelle entspricht, und da es sich nicht geändert hat, erhalten Sie das gleiche Excel-Arbeitsblatt, das Sie mit gestartet. Wenn Sie den Auftrag von DataGridView ‚s Spalten ändern, wie ich annehmen, dass Sie mit dem Code tun unter:

private void btnArg_Click(object sender, EventArgs e) { 
    dataGridView.Columns["BUYER_NAME"].DisplayIndex = 0; 
    dataGridView.Columns["PO_NUMBER"].DisplayIndex = 1; 
    . 
    . 
    . 

... die Indizes auf die Datentabelle den Index in der DataGridView nicht überein. Die Datentabelle wird in Ruhe gelassen und nicht geändert. Da Sie die Spalten DisplayIndex bequem auf die gewünschte Spalte gesetzt haben, können Sie anhand dieser Spalte ermitteln, welche Spalte Sie beim Erstellen der neuen Excel-Datei verwenden möchten.

Mit dem DisplayIndex Wert habe ich (so minimal wie ich konnte) Änderungen an Ihrem btnSave_Click Code vorgenommen. Es sollte wie erwartet funktionieren, aber ich bin zuversichtlich, dass es wahrscheinlich einen viel einfacheren Weg gibt, dies zu erreichen. Es kann einfacher sein, einfach die DataTable Spalten neu zu bestellen. Nur ein Vorschlag ... wahrscheinlich nicht der beste Vorschlag. Vielleicht möchten Sie sich LINQ ansehen.

Änderungen im Code unten bestehen aus: 1) hinzugefügt

excel.Visible = true; 

die Schaffung der neuen Excel-Datei zu zeigen.

2) hinzugefügt int Variable tableCol:

int tableCol = -1; 

es verwendet wird, um die aktuellen Spalten zu bekommen DisplayIndex die richtige Spalte zu erhalten, da sie für die DataGridView geändert haben.

3) Die zwei Zeilen in den doppelten for-Schleifen wurden geändert, als die Daten in das neue Excel-Arbeitsblatt geschrieben wurden. Die erste Zeile für die Zeilenköpfe und die zweite Zeile für die Daten. Da Sie die gleiche Schleife verwenden, um die Header zu erhalten, müssen wir "i" in der zweiten Zeile dekrementieren; Andernfalls werden Sie die erste Zeile verpassen. Auch dies ist ein Hacky-Ansatz, und es kann einfacher sein, die Header einfach in einer eigenen Schleife zu drucken.

// Headers 
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[tableCol].HeaderText; 
// Data 
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i-1].Cells[tableCol].Value.ToString(); 

Aktualisiert btn_Save Veranstaltung:

private void btnSave_Click(object sender, EventArgs e) { 
    //================================================ 
    //CODE TO EXPORT DATAGRID TO EXCEL======= ======== 
    //================================================  
    // Creating a Excel object. 
    Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application(); 
    Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing); 
    Microsoft.Office.Interop.Excel._Worksheet worksheet = null; 
    excel.Visible = true; 

    try { 
    worksheet = workbook.ActiveSheet; 
    worksheet.Name = "ExportedFromDatGrid"; 
    int cellRowIndex = 1; 
    int cellColumnIndex = 1; 
    int tableCol = -1; 
    //Loop through each row and read value from each column. 
    for (int i = 0; i < dataGridView.Rows.Count; i++) { 
     for (int j = 0; j < dataGridView.Columns.Count; j++) { 
     // Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check. 
     tableCol = dataGridView.Columns[j].DisplayIndex; 
     if (cellRowIndex == 1) { 
      //worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[j].HeaderText; 
      worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[tableCol].HeaderText; 
     } 
     else { 
      //worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString(); 
      worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i-1].Cells[tableCol].Value.ToString(); 
     } 
     cellColumnIndex++; 
     } 
     cellColumnIndex = 1; 
     cellRowIndex++; 
    } 
    //Getting the location and file name of the excel to save from user. 
    SaveFileDialog saveDialog = new SaveFileDialog(); 
    saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; 
    saveDialog.FilterIndex = 2; 
    if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { 
     workbook.SaveAs(saveDialog.FileName); 
     MessageBox.Show("Export Successful"); 
    } 
    } 
    catch (System.Exception ex) { 
    MessageBox.Show(ex.Message); 
    } 
    finally { 
    excel.Quit(); 
    workbook = null; 
    excel = null; 
    } 
} 

hoffe, das hilft!

+0

Danke, John. Ich werde mich auf die Verwendung von Interop konzentrieren und DataGridView ausschließen, die ich nur für den visuellen Effekt hinzugefügt habe. Was deine Frage zu den zwei verschiedenen Excel-Bibliotheken anbelangt, so denke ich, dass du bemerkt hast, dass ich ein Neuling in C# bin und ich von verschiedenen Quellen inspiriere, jeder mit seinem einen Ansatz. Vielen Dank für Ihre Antwort! – IzyDece

Verwandte Themen