2016-08-29 21 views
13

私はそれが動作することを知って、このコードを持って、高速エクスポートすべてのセルの書式を持つExcelにDataGridViewの

CopyAlltoClipboard(dataGridViewControl); 
Microsoft.Office.Interop.Excel.Application xlexcel; 
Microsoft.Office.Interop.Excel.Workbook xlWorkBook; 
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet; 
object misValue = System.Reflection.Missing.Value; 
xlexcel = new Excel.Application(); 
xlexcel.Visible = true; 
xlWorkBook = xlexcel.Workbooks.Add(misValue); 
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); 
xlWorkSheet.Name = page.Name; 
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1]; 
CR.Select(); 
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true); 
((Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Range["A1"]).EntireColumn.Delete(null); // delete the first column that has rows indexes 
xlWorkBook.SaveAs(fileName); 

private void CopyAlltoClipboard(DataGridView dataGridViewControl) 
{ 
    dataGridViewControl.SelectAll(); 
    DataObject dataObj = dataGridViewControl.GetClipboardContent(); 
    if (dataObj != null) 
     Invoke((Action)(() => { Clipboard.SetDataObject(dataObj); })); 
} 

コードが正常に動作しますが、それはエクセルでのみ値をコピーし、しませんまた、セルの書式をコピーしてください(テキスト、背景色、フォント、枠線などを囲みます) 誰も私に助けてくれますか?このコードを完成させるには、DataGridViewのような正確なフォーマットが必要ですか?

+0

から背景色は、あなたがこれらを点検したの下にこのコードで://stackoverflow.com/questions/9005721/how-to-keep-colors-when-copy-pasting-from-datagridview-to-excel)、[Datagridviewをクリップボードにフォーマットする](http://stackoverflow.com/質問/ 3829487/datagridview-to-clipboard-with-formatting)?また、[Excel(C#)にエクスポートするときにDataGridView形式を維持](https://social.msdn.microsoft.com/Forums/office/en-US/f615a10a-dcb9-440c-afb0-68d296cb0361/)もあります。 maintain-datagridview-format-excelc-excelc-forum = exceldev) – uTeisT

答えて

2

質問の要点は、DataGridViewのクリップボードを使用して、セルの書式設定が含まれていないことです。クリップボードには書式設定が含まれていないので、セルスタイルを個別に設定しなければならないというパフォーマンスの元々の問題に戻っています。Interopを使用すると非常に遅いです。

この場合、InteropではなくXMLを使用してExcelファイルを作成する方が効果的です。以下はClosedXMLを使用してDataGridViewを書式設定してExcelにエクスポートする方法です。

using ClosedXML.Excel; 

public void ExportToExcelWithFormatting(DataGridView dataGridView1) 
{ 
    string fileName; 

    SaveFileDialog saveFileDialog1 = new SaveFileDialog(); 
    saveFileDialog1.Filter = "xls files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; 
    saveFileDialog1.Title = "To Excel"; 
    saveFileDialog1.FileName = this.Text + " (" + DateTime.Now.ToString("yyyy-MM-dd") + ")"; 

    if (saveFileDialog1.ShowDialog() == DialogResult.OK) 
    { 
     fileName = saveFileDialog1.FileName; 
     var workbook = new XLWorkbook(); 
     var worksheet = workbook.Worksheets.Add(this.Text); 
     for (int i = 0; i < dataGridView1.Columns.Count; i++) 
     { 
      worksheet.Cell(1, i + 1).Value = dataGridView1.Columns[i].Name; 
     } 

     for (int i = 0; i < dataGridView1.Rows.Count; i++) 
     { 
      for (int j = 0; j < dataGridView1.Columns.Count; j++) 
      { 
       worksheet.Cell(i + 2, j + 1).Value = dataGridView1.Rows[i].Cells[j].Value.ToString(); 

       if (worksheet.Cell(i + 2, j + 1).Value.ToString().Length > 0) 
       { 
        XLAlignmentHorizontalValues align; 

        switch (dataGridView1.Rows[i].Cells[j].Style.Alignment) 
        { 
         case DataGridViewContentAlignment.BottomRight: 
          align = XLAlignmentHorizontalValues.Right; 
          break; 
         case DataGridViewContentAlignment.MiddleRight: 
          align = XLAlignmentHorizontalValues.Right; 
          break; 
         case DataGridViewContentAlignment.TopRight: 
          align = XLAlignmentHorizontalValues.Right; 
          break; 

         case DataGridViewContentAlignment.BottomCenter: 
          align = XLAlignmentHorizontalValues.Center; 
          break; 
         case DataGridViewContentAlignment.MiddleCenter: 
          align = XLAlignmentHorizontalValues.Center; 
          break; 
         case DataGridViewContentAlignment.TopCenter: 
          align = XLAlignmentHorizontalValues.Center; 
          break; 

         default: 
          align = XLAlignmentHorizontalValues.Left; 
          break; 
        } 

        worksheet.Cell(i + 2, j + 1).Style.Alignment.Horizontal = align; 

        XLColor xlColor = XLColor.FromColor(dataGridView1.Rows[i].Cells[j].Style.SelectionBackColor); 
        worksheet.Cell(i + 2, j + 1).AddConditionalFormat().WhenLessThan(1).Fill.SetBackgroundColor(xlColor); 

        worksheet.Cell(i + 2, j + 1).Style.Font.FontName = dataGridView1.Font.Name; 
        worksheet.Cell(i + 2, j + 1).Style.Font.FontSize = dataGridView1.Font.Size; 

       }           
      } 
     } 
     worksheet.Columns().AdjustToContents(); 
     workbook.SaveAs(fileName); 
     //MessageBox.Show("Done"); 
    } 
} 
8

これは重複していない理由を理解するのに苦労しています。ネット上にはexampleshereがあります。私の驚きに

&多くの研究の後に、フォーマットとHTMLまたはExcelへのエクスポートのDataGridViewのない徹底した例はどこでもインターネット上ではありません -今まであなたに、このコードを見てみる:)

あなたはそれがInteropで大規模なデータセットをコピーする方法をスローを見出したし、代わりにクリップボードを使用することを選択した質問:

dataGridViewControl.SelectAll(); 
DataObject dataObj = dataGridViewControl.GetClipboardContent(); 
if (dataObj != null) 
    Invoke((Action)(() => { Clipboard.SetDataObject(dataObj); })); 

THIの核心DataGridViewのクリップボードを使用してもセルの書式設定が含まれていません。クリップボードには書式設定が含まれていないので、セルスタイルを個別に設定しなければならないという、元来のパフォーマンス低下の問題に戻っています。Interopを使用すると非常に遅いです。

この場合には、XMLの代わりに、相互運用を使用してExcelファイルを作成するために、あなたのプロジェクトのために良い仕事かもしれません。私は最初にこれが良い回避策であると思っていましたが、DartAlexによるもう1つの答えは、クリップボードメソッドで使用できる答えをコード化すると考えていたことを示しています。テストデータは

enter image description here

//==================================================== 
//DataGridView Export To HTML by Jeremy Thompson: https://stackoverflow.com/questions/39210329/ 
//==================================================== 
public string ConvertDataGridViewToHTMLWithFormatting(DataGridView dgv) 
{ 
    StringBuilder sb = new StringBuilder(); 
    //create html & table 
    sb.AppendLine("<html><body><center><table border='1' cellpadding='0' cellspacing='0'>"); 
    sb.AppendLine("<tr>"); 
    //create table header 
    for (int i = 0; i < dgv.Columns.Count; i++) 
    { 
     sb.Append(DGVHeaderCellToHTMLWithFormatting(dgv, i)); 
     sb.Append(DGVCellFontAndValueToHTML(dgv.Columns[i].HeaderText, dgv.Columns[i].HeaderCell.Style.Font)); 
     sb.AppendLine("</td>"); 
    } 
    sb.AppendLine("</tr>"); 
    //create table body 
    for (int rowIndex = 0; rowIndex < dgv.Rows.Count; rowIndex++) 
    { 
     sb.AppendLine("<tr>"); 
     foreach (DataGridViewCell dgvc in dgv.Rows[rowIndex].Cells) 
     { 
      sb.AppendLine(DGVCellToHTMLWithFormatting(dgv, rowIndex, dgvc.ColumnIndex)); 
      string cellValue = dgvc.Value == null ? string.Empty : dgvc.Value.ToString(); 
      sb.AppendLine(DGVCellFontAndValueToHTML(cellValue, dgvc.Style.Font)); 
      sb.AppendLine("</td>"); 
     } 
     sb.AppendLine("</tr>"); 
    } 
    //table footer & end of html file 
    sb.AppendLine("</table></center></body></html>"); 
    return sb.ToString(); 
} 

//TODO: Add more cell styles described here: https://msdn.microsoft.com/en-us/library/1yef90x0(v=vs.110).aspx 
public string DGVHeaderCellToHTMLWithFormatting(DataGridView dgv, int col) 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.Append("<td"); 
    sb.Append(DGVCellColorToHTML(dgv.Columns[col].HeaderCell.Style.ForeColor, dgv.Columns[col].HeaderCell.Style.BackColor)); 
    sb.Append(DGVCellAlignmentToHTML(dgv.Columns[col].HeaderCell.Style.Alignment)); 
    sb.Append(">"); 
    return sb.ToString(); 
} 

public string DGVCellToHTMLWithFormatting(DataGridView dgv, int row, int col) 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.Append("<td"); 
    sb.Append(DGVCellColorToHTML(dgv.Rows[row].Cells[col].Style.ForeColor, dgv.Rows[row].Cells[col].Style.BackColor)); 
    sb.Append(DGVCellAlignmentToHTML(dgv.Rows[row].Cells[col].Style.Alignment)); 
    sb.Append(">"); 
    return sb.ToString(); 
} 

public string DGVCellColorToHTML(Color foreColor, Color backColor) 
{ 
    if (foreColor.Name == "0" && backColor.Name == "0") return string.Empty; 

    StringBuilder sb = new StringBuilder(); 
    sb.Append(" style=\""); 
    if (foreColor.Name != "0" && backColor.Name != "0") 
    { 
     sb.Append("color:#"); 
     sb.Append(foreColor.R.ToString("X2") + foreColor.G.ToString("X2") + foreColor.B.ToString("X2")); 
     sb.Append("; background-color:#"); 
     sb.Append(backColor.R.ToString("X2") + backColor.G.ToString("X2") + backColor.B.ToString("X2")); 
    } 
    else if (foreColor.Name != "0" && backColor.Name == "0") 
    { 
     sb.Append("color:#"); 
     sb.Append(foreColor.R.ToString("X2") + foreColor.G.ToString("X2") + foreColor.B.ToString("X2")); 
    } 
    else //if (foreColor.Name == "0" && backColor.Name != "0") 
    { 
     sb.Append("background-color:#"); 
     sb.Append(backColor.R.ToString("X2") + backColor.G.ToString("X2") + backColor.B.ToString("X2")); 
    } 

    sb.Append(";\""); 
    return sb.ToString(); 
} 

public string DGVCellFontAndValueToHTML(string value,Font font) 
{ 
    //If no font has been set then assume its the default as someone would be expected in HTML or Excel 
    if (font == null || font == this.Font && !(font.Bold | font.Italic | font.Underline | font.Strikeout)) return value; 
    StringBuilder sb = new StringBuilder(); 
    sb.Append(" "); 
    if (font.Bold) sb.Append("<b>"); 
    if (font.Italic) sb.Append("<i>"); 
    if (font.Strikeout) sb.Append("<strike>"); 

    //The <u> element was deprecated in HTML 4.01. The new HTML 5 tag is: text-decoration: underline 
    if (font.Underline) sb.Append("<u>"); 

    string size = string.Empty; 
    if (font.Size != this.Font.Size) size = "font-size: " + font.Size + "pt;"; 

    //The <font> tag is not supported in HTML5. Use CSS or a span instead. 
    if (font.FontFamily.Name != this.Font.Name) 
    { 
     sb.Append("<span style=\"font-family: "); 
     sb.Append(font.FontFamily.Name); 
     sb.Append("; "); 
     sb.Append(size); 
     sb.Append("\">"); 
    } 
    sb.Append(value); 
    if (font.FontFamily.Name != this.Font.Name) sb.Append("</span>"); 

    if (font.Underline) sb.Append("</u>"); 
    if (font.Strikeout) sb.Append("</strike>"); 
    if (font.Italic) sb.Append("</i>"); 
    if (font.Bold) sb.Append("</b>"); 

    return sb.ToString(); 
} 

public string DGVCellAlignmentToHTML(DataGridViewContentAlignment align) 
{ 
    if (align == DataGridViewContentAlignment.NotSet) return string.Empty; 

    string horizontalAlignment = string.Empty; 
    string verticalAlignment = string.Empty; 
    CellAlignment(align, ref horizontalAlignment, ref verticalAlignment); 
    StringBuilder sb = new StringBuilder(); 
    sb.Append(" align='"); 
    sb.Append(horizontalAlignment); 
    sb.Append("' valign='"); 
    sb.Append(verticalAlignment); 
    sb.Append("'"); 
    return sb.ToString(); 
} 

private void CellAlignment(DataGridViewContentAlignment align, ref string horizontalAlignment, ref string verticalAlignment) 
{ 
    switch (align) 
    { 
     case DataGridViewContentAlignment.MiddleRight: 
      horizontalAlignment = "right"; 
      verticalAlignment = "middle"; 
      break; 
     case DataGridViewContentAlignment.MiddleLeft: 
      horizontalAlignment = "left"; 
      verticalAlignment = "middle"; 
      break; 
     case DataGridViewContentAlignment.MiddleCenter: 
      horizontalAlignment = "centre"; 
      verticalAlignment = "middle"; 
      break; 
     case DataGridViewContentAlignment.TopCenter: 
      horizontalAlignment = "centre"; 
      verticalAlignment = "top"; 
      break; 
     case DataGridViewContentAlignment.BottomCenter: 
      horizontalAlignment = "centre"; 
      verticalAlignment = "bottom"; 
      break; 
     case DataGridViewContentAlignment.TopLeft: 
      horizontalAlignment = "left"; 
      verticalAlignment = "top"; 
      break; 
     case DataGridViewContentAlignment.BottomLeft: 
      horizontalAlignment = "left"; 
      verticalAlignment = "bottom"; 
      break; 
     case DataGridViewContentAlignment.TopRight: 
      horizontalAlignment = "right"; 
      verticalAlignment = "top"; 
      break; 
     case DataGridViewContentAlignment.BottomRight: 
      horizontalAlignment = "right"; 
      verticalAlignment = "bottom"; 
      break; 

     default: //DataGridViewContentAlignment.NotSet 
      horizontalAlignment = "left"; 
      verticalAlignment = "middle"; 
      break; 
    } 
} 


//Easy repro - copy/paste all this code in a Winform app! 
public Form1() 
{ 
    InitializeComponent(); 
} 

private void Form1_Load(object sender, EventArgs e) 
{ 
    string configFile = System.IO.Path.Combine(Application.StartupPath.Replace("\\bin\\Debug", ""), "testData.csv"); 
    List<string[]> rows = System.IO.File.ReadAllLines(configFile).Select(x => x.Split(',')).ToList(); 

    DataTable dataTable = new DataTable(); 
    dataTable.Columns.Add("testing"); 
    dataTable.Columns.Add("one"); 
    dataTable.Columns.Add("two"); 
    dataTable.Columns.Add("three"); 
    rows.ForEach(x => { dataTable.Rows.Add(x); }); 
    this.dgv.DataSource = dataTable; 

    dgv.Columns[0].HeaderCell.Style.Font = new Font(this.Font, FontStyle.Strikeout); 

    dgv[0, 0].Style.BackColor = Color.Aqua; 
    dgv[1, 0].Style.Alignment = DataGridViewContentAlignment.BottomRight; 
    dgv[2, 0].Style.Font = new Font(new FontFamily("Calibri"),(float)16); 
    dgv[3, 0].Style.ForeColor = Color.Red; 

    dgv[0, 1].Style.Font = new Font(this.Font, FontStyle.Bold); 
    dgv[1, 1].Style.Font = new Font(this.Font, FontStyle.Underline); 
    dgv[2, 1].Style.Font = new Font(this.Font, FontStyle.Italic); 
    dgv[3, 1].Style.Font = new Font(this.Font, FontStyle.Bold | FontStyle.Underline); 
    dgv[3, 1].Style.ForeColor = Color.Green; 
    dgv[3, 1].Style.BackColor = Color.Yellow; 

    dgv[0, 2].Style.Font = new Font(new FontFamily("Times New Roman"), (float)18); 
    dgv[1, 2].Style.Font = new Font(new FontFamily("Georgia"), (float)12); 
    dgv[2, 2].Style.Font = new Font(new FontFamily("Arial"), (float)14); 
    dgv[3, 2].Style.Font = new Font(new FontFamily("Verdana"), (float)18); 

    dgv[0, 3].Style.Font = new Font(new FontFamily("Courier New"), (float)11); 
    dgv[1, 3].Style.Font = new Font(new FontFamily("Lucida Console"), (float)18); 
    dgv[2, 3].Style.Font = new Font(new FontFamily("Times"), (float)14); 
    dgv[3, 3].Style.Font = new Font(new FontFamily("serif"), (float)12); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    string dgvToHTMLTable = ConvertDataGridViewToHTMLWithFormatting(dgv); 
    Clipboard.SetText(dgvToHTMLTable); 
} 

の書式でHTMLのテーブルに

のDataGridViewしてExcelへ:をフォーマットしてDataGridViewのHTMLコピーを取得し、Excelにそれを貼り付けます。 csv:

Magic、Abra、Cadabra、Boom!
符号化、楽しみ、YeeHaa、ABS TableName
こんにちは、世界Population.html、表1.
人口統計、310102.xls、Comp.html、表2。

私がしようとすると拡大し、それを改良し、それを維持するために他の人のためのGitHubプロジェクトとして、このコードを利用できるようになります最新のHTMLやエクセルのバージョンで。

0

interopとEPPlusを使用して解決策を見つけたようです。私は上記のコードをExcelで値をコピーし、次にこのコード(EPPlusコード)を使ってdataGridViewからフォーマットを取得するだけです。 このコードは、dataGridViewから取得するもの、または使用したいものです。 [?DataGridViewのからのコピー&ペーストが秀でているときの色を保つ方法](HTTP:私は最初の行からWrapTextを撮りたかったし、各書かれたセル

private void FinalizeWorkbook(DataTableReportParam reportParam, DataGridView dataGridViewControl) 
{ 
    FileInfo newFile = new FileInfo(reportParam.FileName); 
    ExcelPackage pck = new ExcelPackage(newFile); 
    IWorksheet worksheet = pck.Workbook.Worksheets[1]; 

    // wrap text and color the crashes with problems (header) 
    for (int col = 1; col <= worksheet.Dimension.End.Column; col++) 
    { 
     worksheet[1, col].WrapText = true; 
     worksheet[1, col].AutofitRows(); 
     if (String.Compare(dataGridViewControl[col - 1, 0].Style.BackColor.Name, "0") != 0) 
      worksheet[1, col].CellStyle.Color = dataGridViewControl[col - 1, 0].Style.BackColor; 
    } 

    // color the cells 
    for (int row = 2; row <= worksheet.Dimension.End.Row; row++) 
    { 
     for (int col = 1; col <= worksheet.Dimension.End.Column; col++) 
     { 
      if (String.Compare(dataGridViewControl[col - 1, row - 1].Style.BackColor.Name, "0") != 0) 
       worksheet[row, col].CellStyle.Color = dataGridViewControl[col - 1, row - 1].Style.BackColor; 
     } 
    } 
    //save and dispose 
    pck.Save(); 
    pck.Dispose(); 
} 
関連する問題