【问题标题】:Find a particular cell value and delete row afterwards excel c#找到一个特定的单元格值并在之后删除行excel c#
【发布时间】:2019-02-21 02:07:39
【问题描述】:

我正在开发一个读取 Excel 文件并在工作表中搜索特定值的程序,比如说 sheetname = "sheet3"。

之后,程序将查看特定列,比如列“D”,并在整个列中搜索数据值。如果数据值存在,则包含该数据值的整行将被删除/隐藏。

目前,我已经设法从一列的excel文件中获取数据值,但无法继续使用代码。我已经尝试了大约 3 天,但无济于事。我将不胜感激!

这是我目前尝试过的代码:

using System.IO;
using System.Linq;
using System;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Collections.Generic;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            const string fileName =
            @"D:\test.xlsx";

            // Retrieve the value in cell D2.
            string value = GetCellValue(fileName, "Sheet3", "D2");

        }
        // Retrieve the value of a cell, given a file name, sheet name, 
        // and address name.
        public static string GetCellValue(string fileName,
            string sheetName,
            string addressName)
        {
            string value = null;

            // Open the spreadsheet document for read-only access.
            using (SpreadsheetDocument document =
                SpreadsheetDocument.Open(fileName, false))
            {
                // Retrieve a reference to the workbook part.
                WorkbookPart wbPart = document.WorkbookPart;

                // Find the sheet with the supplied name, and then use that 
                // Sheet object to retrieve a reference to the first worksheet.
                Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
                  Where(s => s.Name == sheetName).FirstOrDefault();

                // Throw an exception if there is no sheet.
                if (theSheet == null)
                {
                    throw new ArgumentException("sheetName");
                }

                // Retrieve a reference to the worksheet part.
                WorksheetPart wsPart =
                    (WorksheetPart)(wbPart.GetPartById(theSheet.Id));

                // Use its Worksheet property to get a reference to the cell 
                // whose address matches the address you supplied.
                Cell theCell = wsPart.Worksheet.Descendants<Cell>().
                  Where(c => c.CellReference == addressName).FirstOrDefault();

                // If the cell does not exist, return an empty string.
                if (theCell != null)
                {
                    value = theCell.InnerText;

                    // If the cell represents an integer number, you are done. 
                    // For dates, this code returns the serialized value that 
                    // represents the date. The code handles strings and 
                    // Booleans individually. For shared strings, the code 
                    // looks up the corresponding value in the shared string 
                    // table. For Booleans, the code converts the value into 
                    // the words TRUE or FALSE.
                    if (theCell.DataType != null)
                    {
                        switch (theCell.DataType.Value)
                        {
                            case CellValues.SharedString:

                                // For shared strings, look up the value in the
                                // shared strings table.
                                var stringTable =
                                    wbPart.GetPartsOfType<SharedStringTablePart>()
                                    .FirstOrDefault();

                                // If the shared string table is missing, something 
                                // is wrong. Return the index that is in
                                // the cell. Otherwise, look up the correct text in 
                                // the table.
                                if (stringTable != null)
                                {
                                    value =
                                        stringTable.SharedStringTable
                                        .ElementAt(int.Parse(value)).InnerText;
                                }
                                break;

                            case CellValues.Boolean:
                                switch (value)
                                {
                                    case "0":
                                        value = "FALSE";
                                        break;
                                    default:
                                        value = "TRUE";
                                        break;
                                }
                                break;
                        }
                    }
                }
            }
            return value;
        }
    }
}

附:我只尝试过 OpenXML,因为我要使用的服务器没有安装任何 Microsoft Excel 或任何其他软件。因此,我无法使用 Microsoft.Office.Interop.Excel 来完成此任务。请就此事提供任何帮助。谢谢。

【问题讨论】:

    标签: c# excel openxml


    【解决方案1】:

    我建议您使用 NPOI 库而不是 OpenXML。 NPOI 是一个开源库,无需安装任何办公软件即可读写 Microsoft Office 文档。它是 Java POI 库的 .NET 端口。您可以在网上找到许多示例。

    以下 C# 控制台程序使用 NPOI 执行您所要求的操作。

    using System;
    using System.IO;
    
    using NPOI.SS.UserModel;
    using NPOI.XSSF.UserModel;
    
    public class Program
    {
        public static void Main(string[] args)
        {
            const string FileName = @"d:\test.xlsx";
            IWorkbook workbook = OpenWorkBook(FileName);
    
            ISheet sheet = workbook.GetSheet("Sheet3");
            HideRows(sheet);
            DeleteRows(sheet);
    
            SaveWorkBook(workbook, FileName);
    
            Console.WriteLine("Done. Press any key");
            Console.ReadKey();
        }
    
        private static IWorkbook OpenWorkBook(string workBookName)
        {
            using (FileStream file = new FileStream(workBookName, FileMode.Open, FileAccess.Read))
            {
                return new XSSFWorkbook(file);
            }
        }
    
        private static void HideRows(ISheet sheet)
        {
    
            for (int rowIndex = 0; rowIndex <= sheet.LastRowNum; rowIndex++)
            {
                IRow row = sheet.GetRow(rowIndex);
                if (row == null) continue; // Completely unused row returns null
                ICell cell = row.GetCell(3); // 0-based column index: 0=column A, 1=B, etc
                if (cell != null && cell.StringCellValue == "HideMe")
                {
                    row.Hidden = true;
                }
            }
        }
    
        private static void DeleteRows(ISheet sheet)
        {
            // When deleting we must iterate rows in reverse sequence
            for (int rowIndex = sheet.LastRowNum; rowIndex >= 0; rowIndex--)
            {
                IRow row = sheet.GetRow(rowIndex);
                if (row == null) continue;
                ICell cell = row.GetCell(3);
                if (cell != null && cell.StringCellValue == "DeleteMe")
                {
                    // use ShiftRows to actually delete the row:
                    sheet.ShiftRows(row.RowNum+1, sheet.LastRowNum, -1);
                }
            }
        }
    
        private static void SaveWorkBook(IWorkbook workbook, string workBookName)
        {
            string newFileName = Path.ChangeExtension(workBookName, "new.xlsx");
            using (FileStream file = new FileStream(newFileName, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(file);
            }
    
            string backupFileName = Path.ChangeExtension(workBookName, "bak.xlsx");
            File.Replace(newFileName, workBookName, backupFileName);
        }
    }
    

    【讨论】:

    • 您好,非常感谢您的帮助!我设法让它工作。我唯一遇到的问题是,每当我在运行程序后打开 excel 文件时,我都会收到一个错误,即 excel 文件已损坏 - “Excel 在“test.xlsx”中发现了不可读的内容。我可以知道为什么会这样吗?谢谢你这么多
    • 这可能与您使用的特定版本的 Excel 不兼容。我使用 Excel 2013 进行了测试。我建议您从只有一张工作表的工作簿开始,完全为空(更改程序代码以查找 sheet1 而不是 sheet3),然后查看您可以在程序运行后打开它,然后从那里开始.另外,您知道吗,您可以将 .xlsx 文件重命名为 .zip 然后解压缩:这样做并比较前后以获得一些线索。
    • 嗨,好的。我会仔细看看的。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 2018-06-24
    • 2018-10-06
    • 1970-01-01
    • 2015-08-08
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多