简易的便利数据到excel方法(支持分组,一组一个表文件)

57 阅读3分钟
Dim excelapp As Excel.Application = Nothing  ' 声明 Excel 应用程序对象
Dim workbook As Excel.Workbook = Nothing  ' 声明 Excel 工作簿对象
Dim worksheet As Excel.Worksheet = Nothing  ' 声明 Excel 工作表对象
Dim range As Excel.Range = Nothing  ' 声明 Excel 范围对象
Dim dt As DataTable = Nothing  ' 声明数据表对象
Try
    DBCONNECT.DB_CONNECT()  ' 连接到数据库

    Dim sb = GetSearchSql()  ' 获取查询 SQL
    sb.AppendLine("ORDER BY")  ' 添加排序子句
    sb.AppendLine("    KOUBAN_YOU_TRN.KOUBAN_EDA_NO,")  ' 按 KOUBAN_EDA_NO 排序
    sb.AppendLine("    KOUBAN_YOU_TRN.KOUBAN_YOU_NO")  ' 按 KOUBAN_YOU_NO 排序
    Dim records As SqlDataReader = DBCONNECT.ExecuteReader(sb.ToString, GetSearchPatameter().ToArray)  ' 执行查询并获取数据记录
    dt = DBCONNECT.ConvertDataReaderToDataTable(records)  ' 将数据记录转换为 DataTable

    Dim result As IEnumerable(Of IGrouping(Of String, DataRow)) = dt.Rows.Cast(Of DataRow)().GroupBy(Function(dr) dr("KOUBAN_EDA_NO").ToString())  ' 按 KOUBAN_EDA_NO 对数据进行分组

    Dim kankyomstentity = KankyoMstSql.GetKankyoInfo()  ' 获取环境信息
    If kankyomstentity Is Nothing Then  ' 如果未获取到环境信息
        MessageBox.Show(String.Format(MessageConst.DataNotFoundError, "工番输入检查列表"), "通知")  ' 显示错误消息
        Return  ' 退出方法
    End If
    Dim filepath = Path.Combine(kankyomstentity.TEMP_PATH, TempFileConst.TEMP_KOUBAN_CHECK_LIST)  ' 获取模板文件路径
    If Not File.Exists(filepath) Then  ' 如果模板文件不存在
        MessageBox.Show(MessageConst.ExcelTempFileNotFoundError, "通知")  ' 显示错误消息
        Return  ' 退出方法
    End If

    excelapp = New Excel.Application With {
            .Visible = True,  ' 设置 Excel 应用程序可见
            .DisplayAlerts = False  ' 禁用显示警告
        }
    workbook = excelapp.Workbooks.Add(filepath)  ' 打开模板文件

    ' 获取模板工作表,假设它是第一个工作表
    Dim templateSheet As Excel.Worksheet = DirectCast(workbook.Sheets(1), Excel.Worksheet)

    For Each group As IGrouping(Of String, DataRow) In result  ' 遍历每个分组
        Dim groupCount As Integer = group.Count()  ' 获取分组中的行数
        Dim data(groupCount - 1, dt.Columns.Count - 1) As Object  ' 声明数据数组
        Dim rowindex As Integer = 0  ' 行索引
        For Each dr As DataRow In group  ' 遍历分组中的每一行
            Dim colindex As Integer = 0  ' 列索引
            data(rowindex, colindex) = dr("KOUBAN_YOU_NO").ToString()  ' 获取 KOUBAN_YOU_NO
            colindex += 1  ' 列索引加1
            data(rowindex, colindex) = dr("ITEM_SEKKEI_CODE").ToString()  ' 获取 ITEM_SEKKEI_CODE
            colindex += 1  ' 列索引加1
            data(rowindex, colindex) = dr("ITEM_NAME").ToString()  ' 获取 ITEM_NAME
            colindex += 1  ' 列索引加1
            data(rowindex, colindex) = dr("ITEM_KATA").ToString()  ' 获取 ITEM_KATA
            colindex += 1  ' 列索引加1
            data(rowindex, colindex) = dr("ITEM_ZAIMEKER").ToString()  ' 获取 ITEM_ZAIMEKER
            colindex += 1  ' 列索引加1
            data(rowindex, colindex) = dr("ITEM_SU").ToString()  ' 获取 ITEM_SU
            rowindex += 1  ' 行索引加1
        Next

        ' 复制模板工作表(在上面已经获取到了模板的路径)
        templateSheet.Copy(After:=workbook.Sheets(workbook.Sheets.Count))  ' 在工作簿的最后添加模板的副本
        worksheet = DirectCast(workbook.Sheets(workbook.Sheets.Count), Excel.Worksheet)  ' 获取新创建的工作表
        
        Dim firstRow As DataRow = group.First()  ' 获取分组中的第一行
        worksheet.Name = firstRow("KOUBAN_NO").ToString + "_" + group.Key.ToString()  ' 设置工作表名称
        worksheet.Range("C4").Value = firstRow("KOUBAN_NO")  ' 填充 KOUBAN_NO
        worksheet.Range("C5").Value = firstRow("KOUBAN_EDA_NO")  ' 填充 KOUBAN_EDA_NO
        worksheet.Range("E4").Value = firstRow("JYUCHU_ITEM_NAME")  ' 填充 JYUCHU_ITEM_NAME
        worksheet.Range("E5").Value = firstRow("KOUBAN_EDA_NAME")  ' 填充 KOUBAN_EDA_NAME
        worksheet.Range("E6").Value = firstRow("JYUCHU_SU")  ' 填充 JYUCHU_SU
        worksheet.Range("K6").Value = Date.Now.ToString("yyyy/MM/dd")  ' 填充当前日期

        range = worksheet.Range("B9")  ' 获取开始填充数据的单元格
        range.Resize(groupCount, dt.Columns.Count).Value = data  ' 填充数据
    Next

    ' 删除前两个工作表
    DirectCast(workbook.Sheets(1), Excel.Worksheet).Delete()  ' 删除第一个工作表
    DirectCast(workbook.Sheets(1), Excel.Worksheet).Delete()  ' 删除第二个工作表

Catch ex As Exception
    MessageBox.Show(String.Format(MessageConst.ProcessFailedError, "出力"), "通知")  ' 显示错误消息
    Console.WriteLine(ex.Message)  ' 输出错误消息到控制台
    Console.WriteLine(ex.StackTrace)  ' 输出错误堆栈跟踪到控制台
Finally
    DBCONNECT.DB_DISCONNECT()  ' 断开数据库连接
    If range IsNot Nothing Then Utils.ReleaseComObject(range)  ' 释放 range 对象
    If worksheet IsNot Nothing Then Utils.ReleaseComObject(worksheet)  ' 释放 worksheet 对象
    If workbook IsNot Nothing Then Utils.ReleaseComObject(workbook)  ' 释放 workbook 对象
    If excelapp IsNot Nothing Then Utils.ReleaseComObject(excelapp)  ' 释放 excelapp 对象
End Try