【C#桌面客户端系列学习-8】批量导出数据为csv格式

一、需求

实现数据的批量导出,并且导出格式为csv,对于中文要防止乱码。

二、代码

1、在顶部引用System.IO(用于写文件)和System.Text(用于设置编码)

2、单独写一个批量导出方法,在点击事件中调用

  1. 查询数据时使用的 MySqlHelper.ExecuteDataTable是自己封装的数据库工具类

【C#桌面客户端系列学习-4】封装数据库基础操作工具类(CURD)-CSDN博客

4、加了两个辅助方法:

EscapeCsv:CSV字段转义;

ConvertLikes:爱好转换工具

cs 复制代码
using System;
using System.Data;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace test
{
    public partial class tables : Form
    {
        public tables()
        {
            InitializeComponent();
        }
           

        /// <summary>
        /// 批量导出
        /// </summary>
        private void btnExport_Click(object sender, EventArgs e)
        {
            // 查询数据
            string sql = "select * from form order by id asc";
            DataTable dt = MySqlHelper.ExecuteDataTable(sql);

            // 文件名+时间戳
            string fileName = "用户列表_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".csv";
			
			//调用批量导出方法
            ExportToCsv(dt, fileName);
        }

        /// <summary>
        /// 将 DataTable 导出为 CSV 文件
        /// </summary>
        /// <param name="dt">要导出的数据</param>
        /// <param name="defaultFileName">默认文件名</param>
        private void ExportToCsv(DataTable dt, string defaultFileName) {

            if (dt == null || dt.Rows.Count == 0) {
                MessageBox.Show("没有可导出的数据!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 1.弹出保存对话框,让用户选择路径
            using (SaveFileDialog sfd = new SaveFileDialog()) {
                sfd.Filter = "CSV文件(*.csv)|*.csv|所有文件(*.*)|*.*";
                sfd.FilterIndex = 1;
                sfd.FileName = defaultFileName;
                sfd.Title = "请选择导出位置";

                if (sfd.ShowDialog() != DialogResult.OK) {
                    return;     //用户取消
                }

                try
                {
                    // 2.写文件,UTF-8带BOM(防止Excel打开中文乱码)
                    using (StreamWriter sw = new StreamWriter(sfd.FileName, false, new UTF8Encoding(true))) {
                        
                        // 2.1 写表头(用中文表头)
                        string[] headers = {"ID", "标题", "城市", "性别", "爱好", "描述"};
                        sw.WriteLine(string.Join(",", headers));

                        // 2.2 逐行写数据
                        foreach (DataRow row in dt.Rows)
                        {
                            // 性别转换
                            int sexVal = row["sex"] == DBNull.Value ? 0 : Convert.ToInt32(row["sex"]);
                            string sexText = "未知";
                            if (sexVal == 1) sexText = "男";
                            else if (sexVal == 2) sexText = "女";

                            // 爱好转换
                            string likesText = ConvertLikes(row["likes"] == DBNull.Value ? "" : row["likes"].ToString());

                            // 组装单元格
                            string[] cells = {
                                row["id"].ToString(),
                                row["title"].ToString(),
                                row["city"].ToString(),
                                sexText,
                                likesText,
                                row["description"].ToString()
                            };

                            // 逐字段转义(处理逗号、引号、换行)
                            for (int i = 0; i < cells.Length; i++)
                            {
                                cells[i] = EscapeCsv(cells[i]);
                            }

                            sw.WriteLine(string.Join(",", cells));
                        }

                        // 3.提示成功
                        DialogResult result = MessageBox.Show($"导出成功!共{dt.Rows.Count}条。\n文件位置:{sfd.FileName}", "导出完成");
                    }
                }
                catch (Exception ex)
                {

                    MessageBox.Show("导出失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); ;
                }
            }
        }

        /// CSV 字段转义:含逗号、双引号、换行时用双引号包裹
        private string EscapeCsv(string value) {
            if (string.IsNullOrEmpty(value)) return "";

            if (value.Contains(",") || value.Contains("\"") ||
                value.Contains("\n") || value.Contains("\r"))
            {
                return "\"" + value.Replace("\"", "\"\"") + "\"";
            }
            return value;

        }
		
		   // likes 转换工具方法
        private string ConvertLikes(string likes)
        {
            if (string.IsNullOrEmpty(likes)) return "";
            var map = new Dictionary<string, string>
            {
                { "1", "写字" },
                { "2", "阅读" },
                { "3", "发呆" }
            };

            var result = new List<string>();
            foreach (string p in likes.Split(','))
            {
                if (map.ContainsKey(p.Trim()))
                    result.Add(map[p.Trim()]);
            }
            return string.Join("、", result);
        }

    }
}
相关推荐
小嘉丶学长1 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
迪菲赫尔曼1 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
chari克里2 小时前
QT5.15.2 + msvc2022部署全流程说明(windows可联网环境)
开发语言·c++·qt
Hello.Reader2 小时前
tsrs 技术解析用 Rust 移植 TypeScript 7,类型检查还能怎样提速?
开发语言·rust·typescript
透明的玻璃杯2 小时前
VS2015+QT 多线程
开发语言·qt
码匠许师傅3 小时前
【C++三方组件】mbedTLS:面向嵌入式的轻量 TLS
开发语言·c++
迪菲赫尔曼3 小时前
【基础篇 12】把环境与源码接起来:检查 GPU,再安装服务器上的项目
运维·服务器·开发语言·人工智能·python·yolo·目标检测
2601_962885723 小时前
2026 Python 股票数据接口选型指南(横评 + 决策树)
开发语言·python·区块链
咸咸咸虾4 小时前
Microsoft Visual Studio 历史版本与官方安装包链接汇总
ide·microsoft·visual studio
Evand J4 小时前
【PMSM例程4】PMSM电阻辨识与模型补偿EKF,MATLAB例程。附下载链接,包运行成功
开发语言·matlab·电机·ekf·卡尔曼·pmsm