如何将DataGridView导出为PDFth / Excel / Word以进行轻松打印?

时间:2014-03-07 12:36:29

标签: c# printing datagridview

我所拥有的是C#windows表单应用程序中的简单gridview,它由数据库填充。现在我想添加一个功能来打印它。我用谷歌搜索并尝试了不同的方法,但到目前为止还没有任何方法(有些打印空白页,而其他方法则错误打印了数据)。

这是给我最好结果的代码(它不会打印所有可以通过滚动查看的记录)..

    private void button1_Click(object sender, EventArgs e)
    {
        PrintDialog printDialog = new PrintDialog();
        printDialog.Document = printDocument1;
        printDialog.UseEXDialog = true;
        if (DialogResult.OK == printDialog.ShowDialog())
        {
            printDocument1.DocumentName = "Test Page Print";
            printDocument1.Print();
        }
    }

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        Bitmap bm = new Bitmap(this.dgRecords.Width, this.dgRecords.Height);
        this.dgRecords.DrawToBitmap(bm, new Rectangle(0, 0, this.dgRecords.Width, this.dgRecords.Height));
        e.Graphics.DrawImage(bm, 0, 0);
    }

现在我想也许解决方法是,如果我可以将datagridview导出到任何其他文件,如excel表,pdf或word文档,然后我可以从该文件打印它。我曾尝试将其导出为ex​​cel但尚未成功。它只打印标题和一行。

这是excel-export的代码

    private void ToCsV(DataGridView dGV, string filename)
    {
        string stOutput = "";
        string sHeaders = "";
        for (int j = 0; j < dGV.Columns.Count; j++)
            sHeaders = sHeaders.ToString() + Convert.ToString(dGV.Columns[j].HeaderText) + "\t";
        stOutput += sHeaders + "\r\n";
        for (int i = 0; i < dGV.RowCount - 1; i++)
        {
            string stLine = "";
            for (int j = 0; j < dGV.Rows[i].Cells.Count; j++)
                stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
            stOutput += stLine + "\r\n";
        }
        Encoding utf16 = Encoding.GetEncoding(1254);
        byte[] output = utf16.GetBytes(stOutput);
        FileStream fs = new FileStream(filename, FileMode.Create);
        BinaryWriter bw = new BinaryWriter(fs);
        bw.Write(output, 0, output.Length); //write the encoded file
        bw.Flush();
        bw.Close();
        fs.Close();
    }  

    private void button3_Click(object sender, EventArgs e)
    {
        SaveFileDialog sfd = new SaveFileDialog();
        sfd.Filter = "Excel Documents (*.xls)|*.xls";
        sfd.FileName = "export.xls";
        if (sfd.ShowDialog() == DialogResult.OK)
        {
            ToCsV(dgRecords, sfd.FileName);  
        }  
    }

有人可以告诉我,我做错了什么吗?我只需要打印gridview - 无论是直接打印按钮还是将其导出到其他文件都无关紧要。

编辑:

        Microsoft.Office.Interop.Excel.Application ExcelApp =
                 new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel._Workbook ExcelBook;
        Microsoft.Office.Interop.Excel._Worksheet ExcelSheet;

        int i = 0;
        int j = 0;

        //create object of excel
        ExcelBook = (Microsoft.Office.Interop.Excel._Workbook)ExcelApp.Workbooks.Add(1);
        ExcelSheet = (Microsoft.Office.Interop.Excel._Worksheet)ExcelBook.ActiveSheet;
        //export header
        for (i = 1; i <= this.dataGridView1.Columns.Count; i++)
        {
            ExcelSheet.Cells[1, i] = this.dataGridView1.Columns[i - 1].HeaderText;
        }

        //export data
        for (i = 1; i <= this.dataGridView1.RowCount; i++)
        {
            for (j = 1; j <= dataGridView1.Columns.Count; j++)
            {
                ExcelSheet.Cells[i + 1, j] = dataGridView1.Rows[i - 1].Cells[j - 1].Value;
            }
        }

        ExcelApp.Visible = true;

        //set font Khmer OS System to data range
            Microsoft.Office.Interop.Excel.Range myRange = ExcelSheet.get_Range(
                ExcelSheet.Cells[1, 1],
                ExcelSheet.Cells[this.dataGridView1.RowCount + 1,
                    this.dataGridView1.Columns.Count]);

        Microsoft.Office.Interop.Excel.Font x = myRange.Font;
        x.Name = "Arial";
        x.Size = 10;

        //set bold font to column header
        myRange = ExcelSheet.get_Range(ExcelSheet.Cells[1, 1],
                                 ExcelSheet.Cells[1, this.dataGridView1.Columns.Count]);
        x = myRange.Font;
        x.Bold = true;
        //autofit all columns
        myRange.EntireColumn.AutoFit();

        //
        ExcelSheet = null;
        ExcelBook = null;
        ExcelApp = null;

好的,所以我尝试了这种导出方法excel并且工作正常,它打开了一张包含来自我的数据网格的所有数据的Excel工作表,但在打开excel工作表后,它会生成RuntimeBinder Exception

        'object' does not contain a definition for 'get_Range'

在这一行

        Microsoft.Office.Interop.Excel.Range myRange = ExcelSheet.get_Range(
                ExcelSheet.Cells[1, 1],
                ExcelSheet.Cells[this.dataGridView1.RowCount + 1,
                    this.dataGridView1.Columns.Count]);

似乎有什么问题?我无法弄明白......

1 个答案:

答案 0 :(得分:0)

DataGridView不支持直接打印功能。您已经开始正确地使用PrintDocument并处理PrintPage事件。

在打印页面事件处理程序中,您必须逐行打印DataGridView。有关详细信息,请参阅此article

示例代码:

具有类级别变量int rowIndex=0;

PrintPage event handler

int rowTop=e.MarginBounds.Top;
bool needMorePages=false;
while (rowIndex<= dataGridView1.Rows.Count - 1)
{
    DataGridViewRow row = dataGridView1.Rows[rowIndex];
    if(rowTop + row.Height >= e.MarginBounds.Top + e.MarginBounds.Height)
    {
        needMorePages = true;
        break;
    }
    foreach (DataGridViewCell Cell in row.Cells)
    {
        //draw cell content
    }
    rowTop += row.Height;
    rowIndex++;
}
e.HasMorePages = needMorePages;