วิธีอ่านไฟล์โดยใช้ NPOI


87

ฉันพบว่า NPOI สามารถเขียนไฟล์ Excel ด้วย C # ได้ดีมาก

แต่ฉันต้องการเปิดอ่านและแก้ไขไฟล์ Excel ใน C #

ฉันจะทำเช่นนี้ได้อย่างไร?

คำตอบ:


153

อ่านตัวอย่างง่ายๆด้านล่าง:

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;

//.....

private void button1_Click(object sender, EventArgs e)
{
    HSSFWorkbook hssfwb;
    using (FileStream file = new FileStream(@"c:\test.xls", FileMode.Open, FileAccess.Read))
    {
        hssfwb= new HSSFWorkbook(file);
    }

    ISheet sheet = hssfwb.GetSheet("Arkusz1");
    for (int row = 0; row <= sheet.LastRowNum; row++)
    {
        if (sheet.GetRow(row) != null) //null is when the row only contains empty cells 
        {
            MessageBox.Show(string.Format("Row {0} = {1}", row, sheet.GetRow(row).GetCell(0).StringCellValue));
        }
    }
}  

โดยวิธีการ: บนเว็บไซต์ NPOI ที่นี่ในส่วนดาวน์โหลดมีแพ็คเกจตัวอย่าง - ชุดตัวอย่าง C # ลองถ้าคุณยังไม่ได้ :)


1
stackoverflow.com/questions/13333413/…มีตัวอย่างที่ดีในการป้อนไฟล์ excel ไปยัง datatable
Roger Deep

แต่ฉันมีข้อสงสัยวิธีอ่านฟิลด์ไฮเปอร์ลิงก์และแยกฟิลด์นั้นออกเป็นสองเอนทิตี ฉันต้องการแยกสิ่งเหล่านี้และแสดงในเอนทิตีเดียวพร้อมไฮเปอร์ลิงก์บนพื้นหลัง - คลิกได้ - และป้ายกำกับควรเป็น freetext ที่เป็นสัญลักษณ์ของไฮเปอร์ลิงก์
userAZLogicApps

คลาส HSSFWorkbook ใช้สำหรับ Excel เวอร์ชันก่อนหน้า 2007 สำหรับเวอร์ชันที่ใหม่กว่าคุณต้องใช้สิ่งนี้: var workbook = XSSFWorkbook ใหม่ (fileStream);
todji

26

การพึ่งพาโรงงานสมุดงานเพื่อสร้างอินสแตนซ์อ็อบเจ็กต์สมุดงานอาจเป็นประโยชน์เนื่องจากเมธอดจากโรงงานจะทำการตรวจจับ xls หรือ xlsx ให้คุณ อ้างอิง: http://apache-poi.1045710.n5.nabble.com/How-to-check-for-valid-excel-files-using-POI-without-checking-the-file-extension-td2341055.html

IWorkbook workbook = WorkbookFactory.Create(inputStream);

หากคุณไม่แน่ใจชื่อชีต แต่แน่ใจในดัชนี (อิงจาก 0) คุณสามารถคว้าชีตได้ดังนี้:

ISheet sheet = workbook.GetSheetAt(sheetIndex);

จากนั้นคุณสามารถวนซ้ำตามแถวโดยใช้รหัสที่ได้รับจากคำตอบที่ยอมรับจาก mj82


3
ยอดเยี่ยมขอบคุณ สองสิ่งที่คุ้มค่าเพิ่ม A: ถ้าคุณกำลังใช้FileStream, inputStreamควรจะเป็นFileMode.OpenและFileAccess.Readและเพื่อที่จะบันทึกการเปลี่ยนแปลงของคุณไปยังดิสก์คุณต้องเปิดใหม่FileStreamที่มีFileAccess.Writeได้รับอนุญาต ดูเหมือนจะใช้ไม่ได้กับReadWriteสตรีม นอกเหนือจากWrite()NPOI IWorkbookดูเหมือนจะไม่มีSave()วิธีการ -type ที่อนุญาตให้แก้ไขเวิร์กบุ๊กและบันทึกในภายหลังเช่น Excel Interop
ทรานซิสเตอร์ 1

15

ฉันพบว่า NPOI มีประโยชน์มากสำหรับการทำงานกับไฟล์ Excel นี่คือการใช้งานของฉัน (ความคิดเห็นเป็นภาษาสเปนขออภัยด้วย):

วิธีนี้จะเปิดไฟล์ Excel (ทั้ง xls หรือ xlsx) และแปลงเป็น DataTable

        /// <summary>Abre un archivo de Excel (xls o xlsx) y lo convierte en un DataTable.
    /// LA PRIMERA FILA DEBE CONTENER LOS NOMBRES DE LOS CAMPOS.</summary>
    /// <param name="pRutaArchivo">Ruta completa del archivo a abrir.</param>
    /// <param name="pHojaIndex">Número (basado en cero) de la hoja que se desea abrir. 0 es la primera hoja.</param>
    private DataTable Excel_To_DataTable(string pRutaArchivo, int pHojaIndex)
    {
        // --------------------------------- //
        /* REFERENCIAS:
         * NPOI.dll
         * NPOI.OOXML.dll
         * NPOI.OpenXml4Net.dll */
        // --------------------------------- //
        /* USING:
         * using NPOI.SS.UserModel;
         * using NPOI.HSSF.UserModel;
         * using NPOI.XSSF.UserModel; */
        // AUTOR: Ing. Jhollman Chacon R. 2015
        // --------------------------------- //
        DataTable Tabla = null;
        try
        {
            if (System.IO.File.Exists(pRutaArchivo))
            {

                IWorkbook workbook = null;  //IWorkbook determina si es xls o xlsx              
                ISheet worksheet = null;
                string first_sheet_name = "";

                using (FileStream FS = new FileStream(pRutaArchivo, FileMode.Open, FileAccess.Read))
                {
                    workbook = WorkbookFactory.Create(FS);          //Abre tanto XLS como XLSX
                    worksheet = workbook.GetSheetAt(pHojaIndex);    //Obtener Hoja por indice
                    first_sheet_name = worksheet.SheetName;         //Obtener el nombre de la Hoja

                    Tabla = new DataTable(first_sheet_name);
                    Tabla.Rows.Clear();
                    Tabla.Columns.Clear();

                    // Leer Fila por fila desde la primera
                    for (int rowIndex = 0; rowIndex <= worksheet.LastRowNum; rowIndex++)
                    {
                        DataRow NewReg = null;
                        IRow row = worksheet.GetRow(rowIndex);
                        IRow row2 = null;
                        IRow row3 = null;

                        if (rowIndex == 0)
                        {
                            row2 = worksheet.GetRow(rowIndex + 1); //Si es la Primera fila, obtengo tambien la segunda para saber el tipo de datos
                            row3 = worksheet.GetRow(rowIndex + 2); //Y la tercera tambien por las dudas
                        }

                        if (row != null) //null is when the row only contains empty cells 
                        {
                            if (rowIndex > 0) NewReg = Tabla.NewRow();

                            int colIndex = 0;
                            //Leer cada Columna de la fila
                            foreach (ICell cell in row.Cells)
                            {
                                object valorCell = null;
                                string cellType = "";
                                string[] cellType2 = new string[2];

                                if (rowIndex == 0) //Asumo que la primera fila contiene los titlos:
                                {
                                    for (int i = 0; i < 2; i++)
                                    {
                                        ICell cell2 = null;
                                        if (i == 0) { cell2 = row2.GetCell(cell.ColumnIndex); }
                                        else { cell2 = row3.GetCell(cell.ColumnIndex); }

                                        if (cell2 != null)
                                        {
                                            switch (cell2.CellType)
                                            {
                                                case CellType.Blank: break;
                                                case CellType.Boolean: cellType2[i] = "System.Boolean"; break;
                                                case CellType.String: cellType2[i] = "System.String"; break;
                                                case CellType.Numeric:
                                                    if (HSSFDateUtil.IsCellDateFormatted(cell2)) { cellType2[i] = "System.DateTime"; }
                                                    else
                                                    {
                                                        cellType2[i] = "System.Double";  //valorCell = cell2.NumericCellValue;
                                                    }
                                                    break;

                                                case CellType.Formula:                                                      
                                                    bool continuar = true;
                                                    switch (cell2.CachedFormulaResultType)
                                                    {
                                                        case CellType.Boolean: cellType2[i] = "System.Boolean"; break;
                                                        case CellType.String: cellType2[i] = "System.String"; break;
                                                        case CellType.Numeric:
                                                            if (HSSFDateUtil.IsCellDateFormatted(cell2)) { cellType2[i] = "System.DateTime"; }
                                                            else
                                                            {
                                                                try
                                                                {
                                                                    //DETERMINAR SI ES BOOLEANO
                                                                    if (cell2.CellFormula == "TRUE()") { cellType2[i] = "System.Boolean"; continuar = false; }
                                                                    if (continuar && cell2.CellFormula == "FALSE()") { cellType2[i] = "System.Boolean"; continuar = false; }
                                                                    if (continuar) { cellType2[i] = "System.Double"; continuar = false; }
                                                                }
                                                                catch { }
                                                            } break;
                                                    }
                                                    break;
                                                default:
                                                    cellType2[i] = "System.String"; break;
                                            }
                                        }
                                    }

                                    //Resolver las diferencias de Tipos
                                    if (cellType2[0] == cellType2[1]) { cellType = cellType2[0]; }
                                    else
                                    {
                                        if (cellType2[0] == null) cellType = cellType2[1];
                                        if (cellType2[1] == null) cellType = cellType2[0];
                                        if (cellType == "") cellType = "System.String";
                                    }

                                    //Obtener el nombre de la Columna
                                    string colName = "Column_{0}";
                                    try { colName = cell.StringCellValue; }
                                    catch { colName = string.Format(colName, colIndex); }

                                    //Verificar que NO se repita el Nombre de la Columna
                                    foreach (DataColumn col in Tabla.Columns)
                                    {
                                        if (col.ColumnName == colName) colName = string.Format("{0}_{1}", colName, colIndex);
                                    }

                                    //Agregar el campos de la tabla:
                                    DataColumn codigo = new DataColumn(colName, System.Type.GetType(cellType));
                                    Tabla.Columns.Add(codigo); colIndex++;
                                }
                                else
                                {
                                    //Las demas filas son registros:
                                    switch (cell.CellType)
                                    {
                                        case CellType.Blank: valorCell = DBNull.Value; break;
                                        case CellType.Boolean: valorCell = cell.BooleanCellValue; break;
                                        case CellType.String: valorCell = cell.StringCellValue; break;
                                        case CellType.Numeric:
                                            if (HSSFDateUtil.IsCellDateFormatted(cell)) { valorCell = cell.DateCellValue; }
                                            else { valorCell = cell.NumericCellValue; } break;
                                        case CellType.Formula:
                                            switch (cell.CachedFormulaResultType)
                                            {
                                                case CellType.Blank: valorCell = DBNull.Value; break;
                                                case CellType.String: valorCell = cell.StringCellValue; break;
                                                case CellType.Boolean: valorCell = cell.BooleanCellValue; break;
                                                case CellType.Numeric:
                                                    if (HSSFDateUtil.IsCellDateFormatted(cell)) { valorCell = cell.DateCellValue; }
                                                    else { valorCell = cell.NumericCellValue; }
                                                    break;
                                            }
                                            break;
                                        default: valorCell = cell.StringCellValue; break;
                                    }
                                    //Agregar el nuevo Registro
                                    if (cell.ColumnIndex <= Tabla.Columns.Count - 1) NewReg[cell.ColumnIndex] = valorCell;
                                }
                            }
                        }
                        if (rowIndex > 0) Tabla.Rows.Add(NewReg);
                    }
                    Tabla.AcceptChanges();
                }
            }
            else
            {
                throw new Exception("ERROR 404: El archivo especificado NO existe.");
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return Tabla;
    }

วิธีที่สองนี้ทำ oposite บันทึก DataTable ลงในไฟล์ Excel ใช่อาจเป็น xls หรือ xlsx ใหม่ก็ได้!

        /// <summary>Convierte un DataTable en un archivo de Excel (xls o Xlsx) y lo guarda en disco.</summary>
    /// <param name="pDatos">Datos de la Tabla a guardar. Usa el nombre de la tabla como nombre de la Hoja</param>
    /// <param name="pFilePath">Ruta del archivo donde se guarda.</param>
    private void DataTable_To_Excel(DataTable pDatos, string pFilePath)
    {
        try
        {
            if (pDatos != null && pDatos.Rows.Count > 0)
            {
                IWorkbook workbook = null;
                ISheet worksheet = null;

                using (FileStream stream = new FileStream(pFilePath, FileMode.Create, FileAccess.ReadWrite))
                {
                    string Ext = System.IO.Path.GetExtension(pFilePath); //<-Extension del archivo
                    switch (Ext.ToLower())
                    {
                        case ".xls":
                            HSSFWorkbook workbookH = new HSSFWorkbook();
                            NPOI.HPSF.DocumentSummaryInformation dsi = NPOI.HPSF.PropertySetFactory.CreateDocumentSummaryInformation();
                            dsi.Company = "Cutcsa"; dsi.Manager = "Departamento Informatico";
                            workbookH.DocumentSummaryInformation = dsi;
                            workbook = workbookH;
                            break;

                        case ".xlsx": workbook = new XSSFWorkbook(); break;
                    }

                    worksheet = workbook.CreateSheet(pDatos.TableName); //<-Usa el nombre de la tabla como nombre de la Hoja

                    //CREAR EN LA PRIMERA FILA LOS TITULOS DE LAS COLUMNAS
                    int iRow = 0;
                    if (pDatos.Columns.Count > 0)
                    {
                        int iCol = 0;
                        IRow fila = worksheet.CreateRow(iRow);
                        foreach (DataColumn columna in pDatos.Columns)
                        {
                            ICell cell = fila.CreateCell(iCol, CellType.String);
                            cell.SetCellValue(columna.ColumnName);
                            iCol++;
                        }
                        iRow++;
                    }

                    //FORMATOS PARA CIERTOS TIPOS DE DATOS
                    ICellStyle _doubleCellStyle = workbook.CreateCellStyle();
                    _doubleCellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("#,##0.###");

                    ICellStyle _intCellStyle = workbook.CreateCellStyle();
                    _intCellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("#,##0");

                    ICellStyle _boolCellStyle = workbook.CreateCellStyle();
                    _boolCellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("BOOLEAN");

                    ICellStyle _dateCellStyle = workbook.CreateCellStyle();
                    _dateCellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("dd-MM-yyyy");

                    ICellStyle _dateTimeCellStyle = workbook.CreateCellStyle();
                    _dateTimeCellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("dd-MM-yyyy HH:mm:ss");

                    //AHORA CREAR UNA FILA POR CADA REGISTRO DE LA TABLA
                    foreach (DataRow row in pDatos.Rows)
                    {
                        IRow fila = worksheet.CreateRow(iRow);
                        int iCol = 0;
                        foreach (DataColumn column in pDatos.Columns)
                        {
                            ICell cell = null; //<-Representa la celda actual                               
                            object cellValue = row[iCol]; //<- El valor actual de la celda

                            switch (column.DataType.ToString())
                            {
                                case "System.Boolean":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Boolean);

                                        if (Convert.ToBoolean(cellValue)) { cell.SetCellFormula("TRUE()"); }
                                        else { cell.SetCellFormula("FALSE()"); }

                                        cell.CellStyle = _boolCellStyle;
                                    }
                                    break;

                                case "System.String":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.String);
                                        cell.SetCellValue(Convert.ToString(cellValue));
                                    }
                                    break;

                                case "System.Int32":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Numeric);
                                        cell.SetCellValue(Convert.ToInt32(cellValue));
                                        cell.CellStyle = _intCellStyle;
                                    }
                                    break;
                                case "System.Int64":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Numeric);
                                        cell.SetCellValue(Convert.ToInt64(cellValue));
                                        cell.CellStyle = _intCellStyle;
                                    }
                                    break;
                                case "System.Decimal":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Numeric);
                                        cell.SetCellValue(Convert.ToDouble(cellValue));
                                        cell.CellStyle = _doubleCellStyle;
                                    }
                                    break;
                                case "System.Double":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Numeric);
                                        cell.SetCellValue(Convert.ToDouble(cellValue));
                                        cell.CellStyle = _doubleCellStyle;
                                    }
                                    break;

                                case "System.DateTime":
                                    if (cellValue != DBNull.Value)
                                    {
                                        cell = fila.CreateCell(iCol, CellType.Numeric);
                                        cell.SetCellValue(Convert.ToDateTime(cellValue));

                                        //Si No tiene valor de Hora, usar formato dd-MM-yyyy
                                        DateTime cDate = Convert.ToDateTime(cellValue);
                                        if (cDate != null && cDate.Hour > 0) { cell.CellStyle = _dateTimeCellStyle; }
                                        else { cell.CellStyle = _dateCellStyle; }
                                    }
                                    break;
                                default:
                                    break;
                            }
                            iCol++;
                        }
                        iRow++;
                    }

                    workbook.Write(stream);
                    stream.Close();
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

ด้วย 2 วิธีนี้คุณสามารถเปิดไฟล์ Excel โหลดลงใน DataTable ทำการปรับเปลี่ยนและบันทึกกลับลงในไฟล์ Excel

หวังว่าพวกคุณจะพบว่าสิ่งนี้มีประโยชน์


การอ้างอิงของICSharpCode.SharpZipLib.dllและNPOI.OpenXmlFormats.dllจำเป็นต้องอ่านไฟล์ XLSX
bjan

1
โค้ดด้านบนใช้งานได้ ฉันใช้ Google แปลเพื่อรับความหมายของความคิดเห็นที่เป็นภาษาสเปน ขอบคุณที่ช่วยเหลือ..!
DevMJ

@DevMJ โชคดีที่รหัสไม่ต้องใช้ GTranslator xD
Jhollman

หากคุณไม่ได้ใช้ NPOI.Mapper ให้ลองใช้สิ่งนี้สำหรับการอ่านอย่างง่ายและการทำแผนที่แผ่นงานเช่นกัน: github.com/hidegh/NPOI ส่วนขยาย
baHI

8

ดังที่ Janoulle ชี้ให้เห็นคุณไม่จำเป็นต้องตรวจสอบว่าเป็นส่วนขยายใดหากคุณใช้ WorkbookFactory มันจะทำเพื่อคุณ ฉันเพิ่งต้องใช้โซลูชันโดยใช้ NPOI เพื่ออ่านไฟล์ Excel และนำเข้าที่อยู่อีเมลไปยังฐานข้อมูล sql ปัญหาหลักของฉันคือฉันอาจจะได้รับเค้าโครง Excel ที่แตกต่างกันประมาณ 12 แบบจากลูกค้าที่แตกต่างกันดังนั้นฉันจึงต้องการบางสิ่งที่สามารถเปลี่ยนแปลงได้อย่างรวดเร็วโดยไม่ต้องใช้รหัสมากนัก ฉันลงเอยด้วยการใช้ Npoi.Mapper ซึ่งเป็นเครื่องมือที่ยอดเยี่ยมมาก! ขอแนะนำ!

นี่คือโซลูชันที่สมบูรณ์ของฉัน:

using System.IO;
using System.Linq;
using Npoi.Mapper;
using Npoi.Mapper.Attributes;
using NPOI.SS.UserModel;

namespace JobCustomerImport.Processors
{
    public class ExcelEmailProcessor
    {
        private UserManagementServiceContext DataContext { get; }

        public ExcelEmailProcessor(int customerNumber)
        {
            DataContext = new UserManagementServiceContext();
        }

        public void Execute(string localPath, int sheetIndex)
        {
            IWorkbook workbook;
            using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read))
            {
                workbook = WorkbookFactory.Create(file);
            }

            var importer = new Mapper(workbook);
            var items = importer.Take<MurphyExcelFormat>(sheetIndex);
            foreach(var item in items)
            {
                var row = item.Value;
                if (string.IsNullOrEmpty(row.EmailAddress))
                    continue;

                UpdateUser(row);
            }

            DataContext.SaveChanges();
        }

        private void UpdateUser(MurphyExcelFormat row)
        {
            //LOGIC HERE TO UPDATE A USER IN DATABASE...
        }

        private class MurphyExcelFormat
        {
            [Column("District")]
            public int District { get; set; }

            [Column("DM")]
            public string FullName { get; set; }

            [Column("Email Address")]
            public string EmailAddress { get; set; }

            [Column(3)]
            public string Username { get; set; }

            public string FirstName
            {
                get
                {
                    return Username.Split('.')[0];
                }
            }

            public string LastName
            {
                get
                {
                    return Username.Split('.')[1];
                }
            }
        }
    }
}

ฉันมีความสุขมากกับ NPOI + Npoi.Mapper ( จาก Donny Tian ) ในฐานะโซลูชันการนำเข้า Excel ที่ฉันเขียนบล็อกโพสต์เกี่ยวกับเรื่องนี้โดยดูรายละเอียดเพิ่มเติมเกี่ยวกับโค้ดด้านบนนี้ คุณสามารถอ่านได้ที่นี่ถ้าคุณต้องการ: วิธีที่ง่ายที่สุดที่จะนำเข้าไฟล์ Excel สิ่งที่ดีที่สุดเกี่ยวกับโซลูชันนี้คือมันทำงานได้อย่างสมบูรณ์แบบในสภาพแวดล้อมสีฟ้า / คลาวด์ที่ไม่มีเซิร์ฟเวอร์ซึ่งฉันไม่สามารถใช้กับเครื่องมือ / ไลบรารี Excel อื่น ๆ ได้


ฉันยังคงรอ (2 ปี) สำหรับการเปลี่ยนแปลงทางสถาปัตยกรรมบางอย่างเนื่องจากต้องมีการประมวลผลเพิ่มเติมในบางกรณีที่ไม่ใช่กรณีพิเศษ นี่คือเหตุผลที่ฉันสร้างเครื่องอ่านและผู้ทำแผนที่แบบธรรมดามันต้องมีบรรทัดพิเศษบางอย่าง แต่คุณควบคุมได้ 100% ว่าจะได้อะไรและอย่างไร: github.com/hidegh/NPOI ส่วนขยาย
baHI

6
private DataTable GetDataTableFromExcel(String Path)
    {
        XSSFWorkbook wb;
        XSSFSheet sh;
        String Sheet_name;

        using (var fs = new FileStream(Path, FileMode.Open, FileAccess.Read))
        {
            wb = new XSSFWorkbook(fs);

               Sheet_name= wb.GetSheetAt(0).SheetName;  //get first sheet name
        }
        DataTable DT = new DataTable();
        DT.Rows.Clear();
        DT.Columns.Clear();

        // get sheet
        sh = (XSSFSheet)wb.GetSheet(Sheet_name);

        int i = 0;
        while (sh.GetRow(i) != null)
        {
            // add neccessary columns
            if (DT.Columns.Count < sh.GetRow(i).Cells.Count)
            {
                for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
                {
                    DT.Columns.Add("", typeof(string));
                }
            }

            // add row
            DT.Rows.Add();

            // write row value
            for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
            {
                var cell = sh.GetRow(i).GetCell(j);

                if (cell != null)
                {
                    // TODO: you can add more cell types capatibility, e. g. formula
                    switch (cell.CellType)
                    {
                        case NPOI.SS.UserModel.CellType.Numeric:
                            DT.Rows[i][j] = sh.GetRow(i).GetCell(j).NumericCellValue;
                            //dataGridView1[j, i].Value = sh.GetRow(i).GetCell(j).NumericCellValue;

                            break;
                        case NPOI.SS.UserModel.CellType.String:
                            DT.Rows[i][j] = sh.GetRow(i).GetCell(j).StringCellValue;

                            break;
                    }
                }
            }

            i++;
        }

        return DT;
    }

4
private static ISheet GetFileStream(string fullFilePath)
    {
        var fileExtension = Path.GetExtension(fullFilePath);
        string sheetName;
        ISheet sheet = null;
        switch (fileExtension)
        {
            case ".xlsx":
                using (var fs = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read))
                {
                    var wb = new XSSFWorkbook(fs);
                    sheetName = wb.GetSheetAt(0).SheetName;
                    sheet = (XSSFSheet) wb.GetSheet(sheetName);
                }
                break;
            case ".xls":
                using (var fs = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read))
                {
                    var wb = new HSSFWorkbook(fs);
                    sheetName = wb.GetSheetAt(0).SheetName;
                    sheet = (HSSFSheet) wb.GetSheet(sheetName);
                }
                break;
        }
        return sheet;
    }

    private static DataTable GetRequestsDataFromExcel(string fullFilePath)
    {
        try
        {
            var sh = GetFileStream(fullFilePath);
            var dtExcelTable = new DataTable();
            dtExcelTable.Rows.Clear();
            dtExcelTable.Columns.Clear();
            var headerRow = sh.GetRow(0);
            int colCount = headerRow.LastCellNum;
            for (var c = 0; c < colCount; c++)
                dtExcelTable.Columns.Add(headerRow.GetCell(c).ToString());
            var i = 1;
            var currentRow = sh.GetRow(i);
            while (currentRow != null)
            {
                var dr = dtExcelTable.NewRow();
                for (var j = 0; j < currentRow.Cells.Count; j++)
                {
                    var cell = currentRow.GetCell(j);

                    if (cell != null)
                        switch (cell.CellType)
                        {
                            case CellType.Numeric:
                                dr[j] = DateUtil.IsCellDateFormatted(cell)
                                    ? cell.DateCellValue.ToString(CultureInfo.InvariantCulture)
                                    : cell.NumericCellValue.ToString(CultureInfo.InvariantCulture);
                                break;
                            case CellType.String:
                                dr[j] = cell.StringCellValue;
                                break;
                            case CellType.Blank:
                                dr[j] = string.Empty;
                                break;
                        }
                }
                dtExcelTable.Rows.Add(dr);
                i++;
                currentRow = sh.GetRow(i);
            }
            return dtExcelTable;
        }
        catch (Exception e)
        {
            throw;
        }
    }

อ่านไฟล์ excel และขึ้นอยู่กับนามสกุลไฟล์ทั้ง xls หรือ xlsx แปลงเป็น datatable
Shailesh B. Rathi

ระวังขนาดคอลัมน์ที่แตกต่างกันในไฟล์จะผิดพลาด ไม่ใช่เรื่องง่ายที่จะคิดออกดังนั้นให้ตัด try-catch block ก่อนเพื่อให้ได้ข้อยกเว้นใน dr [j] = cell.StringCellValue; และสังเกตว่าคุณไม่มีคอลัมน์ใน DR;
Roger Deep

3

เนื่องจากคุณได้ขอให้อ่านและแก้ไขไฟล์ xls ฉันจึงเปลี่ยนคำตอบของ @ mj82 ให้ตรงกับความต้องการของคุณ

HSSFWorkbookไม่มีSaveวิธีการ แต่ต้องWriteสตรีม

static void Main(string[] args)
        {
            string filepath = @"C:\test.xls";

            HSSFWorkbook hssfwb;

            using (FileStream file = new FileStream(filepath, FileMode.Open, FileAccess.Read))
            {
                hssfwb = new HSSFWorkbook(file);
            }

            ISheet sheet = hssfwb.GetSheetAt(0);

            for (int row = 0; row <= sheet.LastRowNum; row++)
            {
                if (sheet.GetRow(row) != null) //null is when the row only contains empty cells 
                {
                    // Set new cell value
                    sheet.GetRow(row).GetCell(0).SetCellValue("foo");
                    Console.WriteLine("Row {0} = {1}", row, sheet.GetRow(row).GetCell(0).StringCellValue);
                }
            }

            // Save the file
            using (FileStream file = new FileStream(filepath, FileMode.Open, FileAccess.Write))
            {
                hssfwb.Write(file);
            }

            Console.ReadLine();
        }

ขอขอบคุณที่แสดงวิธีแก้ไข Excel ที่มีอยู่ สิ่งนี้ช่วยฉันได้มาก นี่เป็นตัวอย่างที่ดี หวังว่าจะเป็นประโยชน์กับผู้เริ่มต้น NPOI คนอื่น ๆ เช่นฉัน
劉鎮瑲

0

หากคุณไม่ต้องการใช้ NPOI.Mapper ฉันขอแนะนำให้คุณตรวจสอบวิธีนี้ - จัดการการอ่านเซลล์ excel เป็นประเภทต่างๆและยังมีตัวช่วยในการนำเข้าอย่างง่าย: https://github.com/hidegh/ สช

var data = sheet.MapTo<OrderDetails>(true, rowMapper =>
{
  // map singleItem
  return new OrderDetails()
  {
    Date = rowMapper.GetValue<DateTime>(SheetColumnTitles.Date),

    // use reusable mapper for re-curring scenarios
    Region = regionMapper(rowMapper.GetValue<string>(SheetColumnTitles.Region)),

    Representative = rowMapper.GetValue<string>(SheetColumnTitles.Representative),
    Item = rowMapper.GetValue<string>(SheetColumnTitles.Item),
    Units = rowMapper.GetValue<int>(SheetColumnTitles.Units),
    UnitCost = rowMapper.GetValue<decimal>(SheetColumnTitles.UnitCost),
    Total = rowMapper.GetValue<decimal>(SheetColumnTitles.Total),

    // read date and total as string, as they're displayed/formatted on the excel
    DateFormatted = rowMapper.GetValue<string>(SheetColumnTitles.Date),
    TotalFormatted = rowMapper.GetValue<string>(SheetColumnTitles.Total)
  };
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.