当前位置: 首页 > news >正文

C# | 超简单CSV表格读写操作(轻松将数据保存到CSV,并支持读取还原)

在这里插入图片描述

C# | 超简单CSV表格读写操作(轻松将数据保存到CSV,并支持读取还原)

文章目录

  • C# | 超简单CSV表格读写操作(轻松将数据保存到CSV,并支持读取还原)
    • 一、上位机开发中的CSV应用背景
    • 二、CSV读写实战教学
      • 1. 基本对象序列化
      • 2. 多数据类型处理
      • 3. 集合类型序列化
      • 4. 二进制数据处理
      • 5. 自定义类型支持
      • 6. 表头自定义
      • 7. 属性忽略
      • 8. 大文件完整读写测试
    • 三、安装部署指南
    • 四、感谢阅读

一、上位机开发中的CSV应用背景

在工业自动化上位机开发中,CSV格式数据的生成与解析是常见的核心需求:

  1. 用于设备运行数据的长期记录
  2. 实现与其他系统(如MES/ERP)的数据交换
  3. 生成可人工查阅的生产报表
  4. 调试阶段数据快照保存

传统方式通过硬编码拼接字符串效率低下,且难以处理复杂数据结构。本文将讲解如何使用CsvSerializer类轻松实现CSV文件的生成和读取。


二、CSV读写实战教学

1. 基本对象序列化

/// <summary>
/// 基本学生信息类
/// </summary>
public class SimpleStudent
{
    public int Id { get; set; }
    public string Name { get; set; }
}

var students = new List<SimpleStudent>
{
    new SimpleStudent { Id = 1001, Name = "张三" },
    new SimpleStudent { Id = 1002, Name = "李四" }
};

var csv = new CsvSerializer().ConvertToCsvLines(students);
File.WriteAllLines("simple_students.csv", csv);

2. 多数据类型处理

/// <summary>
/// 复合数据类型演示类
/// </summary>
public class DataTypeDemo
{
    public DateTime RecordTime { get; set; }   // 时间类型
    public float Temperature { get; set; }     // 精确数值
    public bool IsValid { get; set; }          // 布尔类型
}

var data = new DataTypeDemo
{
    RecordTime = DateTime.Now,
    Temperature = 25.36f,
    IsValid = true
};

var serializer = new CsvSerializer();
File.WriteAllLines("data_types.csv", serializer.ConvertToCsvLines(new[] { data }));

3. 集合类型序列化

public class CollectionDemo
{
    public int[] SensorValues { get; set; }          // 整型数组
    public List<double> Voltages { get; set; }       // 泛型列表
}

var demo = new CollectionDemo
{
    SensorValues = new[] { 100, 200, 300 },
    Voltages = new List<double> { 3.3, 5.0, 12.0 }
};

// 生成CSV时集合元素自动以分号分隔
var csvLines = new CsvSerializer().ConvertToCsvLines(new[] { demo });

4. 二进制数据处理

public class BinaryData
{
    public byte[] ImageBuffer { get; set; }  // Base64编码存储
}

var data = new BinaryData
{
    ImageBuffer = File.ReadAllBytes("logo.png")
};

// 生成文件提示:大量二进制数据存入单行可能导致Excel无法打开
File.WriteAllLines("data_binary.csv", serializer.ConvertToCsvLines(new[] { data }));

5. 自定义类型支持

// 定义新的结构体类型
public struct Coordinate
{
    public double X;
    public double Y;
}

// 测试类型
public class CustomTypeDemo 
{ 
	public Coordinate Position { get; set; } 
}

// 注册自定义转换器
var serializer = new CsvSerializer();
serializer.Converters.Add(typeof(Coordinate), new StringConverter<Coordinate>(
    str =>
    {
        var parts = str.Split('|');
        return new Coordinate { X = double.Parse(parts[0]), Y = double.Parse(parts[1]) };
    },
    c => $"{c.X}|{c.Y}"
));

6. 表头自定义

public class MachineData
{
    [CsvColumn("Current Speed (m/min)")]
    public double Speed { get; set; }

    [CsvColumn("Working Temp (°C)")]
    public double Temperature { get; set; }
}

// 生成的CSV标题类似:
// Current Speed (m/min),Working Temp (°C)

7. 属性忽略

public class SecurityData
{
    public string PublicInfo { get; set; }

    [CsvIgnore]
    public string SecretKey { get; set; }  // 不会出现在CSV中
}

8. 大文件完整读写测试

在这里插入图片描述

生成用于测试的随机学生信息表CSV文件:

        /// <summary>
        /// 生成学生信息表
        /// </summary>
        public void GenerateTestCsvFile()
        {
            var serializer = new CsvSerializer();
            const int dataSize = 1000;

            var random = new Random();
            var students = Enumerable.Range(0, dataSize).Select(_ => GenerateRandomStudent(random)).ToList();

            var csv = serializer.ConvertToCsvLines(students);
            File.WriteAllLines("test_data.csv", csv);

            // 打开文件夹
            Process.Start("explorer.exe", "/select," + Path.GetFullPath("test_data.csv"));
            Console.WriteLine($"已生成测试数据文件:{Path.GetFullPath("test_data.csv")}");
        }

        /// <summary>
        /// 生成随机学生数据
        /// </summary>
        private static Student GenerateRandomStudent(Random random)
        {
            return new Student
            {
                // 基础类型
                Id = random.Next(10000, 99999),
                Name = $"Student_{random.Next(1, 1000)}",
                GPA = Math.Round(random.NextDouble() * 4.0, 2),

                // 结构体类型
                Location = new Point(random.Next(0, 100), random.Next(0, 100)),
                ClassSize = new Size(random.Next(30, 60), random.Next(20, 40)),

                // 集合类型
                Marks = Enumerable.Range(0, 5).Select(_ => random.Next(60, 100)).ToArray(),
                Courses = new List<string>
                {
                    $"Course_{random.Next(100, 999)}",
                    $"Course_{random.Next(100, 999)}",
                    $"Course_{random.Next(100, 999)}"
                },

                // 特殊类型
                Grade = (char)('A' + random.Next(0, 5))
            };
        }

        /// <summary>
        /// 测试用学生类(覆盖8种不同数据类型)
        /// </summary>
        private class Student
        {
            // 基础值类型
            public int Id { get; set; }

            // 字符串类型
            public string Name { get; set; }

            // 浮点类型
            public double GPA { get; set; }

            // 结构体类型(Point)
            public Point Location { get; set; }

            // 结构体类型(Size)
            public Size ClassSize { get; set; }

            // 数组类型
            public int[] Marks { get; set; }

            // 泛型集合
            public List<string> Courses { get; set; }

            // 字符类型
            public char Grade { get; set; }
        }

读取CSV文件,还原成对象数组:

// 读取还原数据
var serializer = new CsvSerializer();
var loadedData = serializer.ConvertFromCsvLines<Student>(File.ReadAllLines("test_data.csv"));

三、安装部署指南

通过NuGet包管理器安装:
在这里插入图片描述
通过NuGet包管理器执行:

Install-Package STTech.CodePlus

或使用.NET CLI:

dotnet add package STTech.CodePlus

四、感谢阅读

感谢各位读者耐心阅读,本库将持续迭代工业领域实用组件。如有建议可评论区留言,期待您的使用反馈!

相关文章:

  • Android主流架构模式对比分析
  • 7-字符串
  • RabbitMQ 集群降配
  • 自定义对象处理请求参数
  • Vue3 + ECharts 数据可视化实战指南
  • unity npc射线检测碰撞
  • Java技术专题-Java Agent探针的技术介绍(1)
  • DocumentByParagraphSplitter:LangChain4j中文本处理的“智能切割刀”
  • 防火墙双机热备(主备分担)
  • 神经外科手术规划的实现方案及未来发展方向
  • Java 反射机制详解
  • 4.好事多磨 1
  • 流量密码破解:eBay店铺首页改版后的黄金展示位
  • HTML,CSS,JavaScript
  • 如何有效运营Instagram,降低封号风险?
  • Java的继承:方法;属性?
  • 使用 Google Firebase 控制台和 ESP8266 NodeMCU 的物联网控制 LED
  • 如何理解std::promise和std::future
  • 【conda activate无效】 conda: error: argument COMMAND: invalid choice: ‘activate‘
  • 【css酷炫效果】纯CSS实现悬浮弹性按钮
  • 商务部新闻发言人就出口管制管控名单答记者问
  • 受美关税影响,本田预计新财年净利下降七成,并推迟加拿大建厂计划
  • 福建厦门市副市长、市公安局局长陈育煌出任吉林省公安厅厅长
  • 中国人民抗日战争暨世界反法西斯战争胜利80周年纪念活动标识发布
  • 季子文化与江南文化的根脉探寻与融合
  • 有关部门负责人就《新时代的中国国家安全》白皮书答记者问