zoukankan      html  css  js  c++  java
  • NPOI追加内容到xlsx报错,用Epplus往excle xlsx追加数据

    问题的现象就是,只要不修改xlsx,一直写入或者再次写入xlsx,追加内容都是不会有问题的。但是只要你修改了xlsx,用excle2010或者2007修改了xlsx的内容里面的列宽,或者行高,或者进行其他的操作。再次用NPOI往这个xlsx里面追加内容的时候,就会损坏这个xlsx文件。也就是说,NPOI在读取xlsx,如果这个xlsx不是由xlsx原始生成的,或者是原本是NPOI生成的,但是用户中途进行了修改,哪怕是改动了一丁点儿,比如列宽,行高,那么再次写入的时候xlsx就被写坏了,无法用EXCLE打开,打开会提示当前文件含有格式不正确的数据。

    总结一句话:读写高级版本的xlsx不要使用NPOI, 而要使用EPPLUS。血的教训。被坑了半天时间。

    如果是网站生成数据格式,供用户下载,用下面代码,NPOI没有问题,如果是反复读写的场景,甚至还有用户修改这个excle文件的话,比如电脑端NPOI对这个文件读写,用户在手机端修改同一个文件,建议用EPPLUS.下面是NPOI追加数据的代码。

    public static IWorkbook LoadWorkbook(string filePath)
            {
                IWorkbook workbook;
                using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) //读入excel模板
                {
                    if (filePath.EndsWith("xlsx"))
                    {
                      return  workbook = new XSSFWorkbook(fileStream);
                    }
                    else
                    {
                        return workbook = new HSSFWorkbook(fileStream);
                    }
                   
                }
            }
     private void SaveToExcle()
            {
                try
                {
                    string currentPath = Environment.CurrentDirectory;
                    IWorkbook workbook = LoadWorkbook(currentPath + "\1.xlsx");
    
    
                        ISheet sheet = workbook.GetSheetAt(0); //获取工作表
                        IRow row = sheet.GetRow(0); //得到表头
    
                    using (FileStream fout = new FileStream(currentPath + "\1.xlsx", FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
                    {
                        row = sheet.CreateRow((sheet.LastRowNum + 1)); //在工作表中添加一行
                        ICell cell1 = row.CreateCell(0);
                        cell1.SetCellValue(label_enghlis.Text); //赋值
    
                        ICell cell2 = row.CreateCell(1);
                        cell2.SetCellValue(textBox1.Text); //赋值
    
                        ICell cell3 = row.CreateCell(2);
                        cell3.SetCellValue(label_Rank.Text); //赋值
                        fout.Flush();
                        workbook.Write(fout);
    
    
                    }
                   
                    workbook = null;
                    textBox1.Text = string.Empty;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
               
            }

    以上只要你用excle2007或者excle2010修改excle就问题。

    下面是用的EPPLUS,初始化,创建一个xlsx文件,并且初始化,给sheet名字,表头标题赋值。

    image

    winform初始化,在根目录创建xlsx文件。需要Nuget引入Epplus。using OfficeOpenXml;

    下面是winform初始化,用Epplus组件在根目录建立xlsx文件。

    if (!File.Exists(currentPath + "\1.xlsx")) //不存在则创建
                {
                    FileInfo newFile = new FileInfo(currentPath + @"1.xlsx");
                  
                    using (ExcelPackage package = new ExcelPackage(newFile))
                    {
                        // add a new worksheet to the empty workbook
                        ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("单词本");
                        //Add the headers
                        worksheet.Cells[1, 1].Value = "单词";
                        worksheet.Cells[1, 2].Value = "词义";
                        worksheet.Cells[1, 3].Value = "词频";
                        package.Save();
                      
                    }
                }

    下面是Epplus追加数据到xlsx的代码:

    private void SaveToXlsX()
            {
                try
                {
                    string currentPath = Environment.CurrentDirectory;

                   // ok, we can run the real code of the sample now
                    if (File.Exists(currentPath + "\1.xlsx")) //如果存在则直接打开
                    {
                        FileInfo newFile = new FileInfo(currentPath + @"1.xlsx");

                       using (ExcelPackage package = new ExcelPackage(newFile))
                        {
                            // add a new worksheet to the empty workbook
                            ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
                            //获得最后一行,这里其实获取的是总行数,追加数据的话,需要+1
                            int lastRow = worksheet.Dimension.End.Row;
                            worksheet.Cells[lastRow+1, 1].Value = label_enghlis.Text;
                            worksheet.Cells[lastRow+1, 2].Value = textBox1.Text;
                            worksheet.Cells[lastRow+1, 3].Value = label_Rank.Text;
                            package.Save();

                       }
                    }
                            textBox1.Text = string.Empty;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }

    真正往xlsx追加数据

    image

    image

    excel07以上的版本支持最大行数104 8576行 ,百万行数据。如果是用追加的方式可能会更好。

  • 相关阅读:
    替代或者与 Redis 配合存储十亿级别列表的数据.
    Python中高层次的数据结构,动态类型和动态绑定,使得它非常适合于快速应用开发,也适合于作为胶水语言连接已有的软件部件。
    伪类 伪元素
    模块与你的主业务代码是应该解耦的
    MarkdownPad
    长度区间校验公共方法,引入棉花糖
    不可见字符
    eval is not a function
    for (const k in v){ 变量作用域
    爬虫站点的历史入库数据,对入库数据的无外网处理,幂等操作;反之,不幂等操作
  • 原文地址:https://www.cnblogs.com/caianhua/p/7711658.html
Copyright © 2011-2022 走看看