C# 在c中使用NPOI将xlsx文件转换为xls#

C# 在c中使用NPOI将xlsx文件转换为xls#,c#,asp.net-mvc,npoi,C#,Asp.net Mvc,Npoi,我有一个*.xlsx格式的excel文件。我想在我的MVC Web应用程序中将此文件转换为*.xls格式。在我的应用程序托管服务器中,没有Microsoft.Office软件包。请让我知道我们如何用c#在NPOI中实现它 提前谢谢。这是我的建议: 使用此库可以读取格式为2007的excel文件 使用此库可将文件另存为2003格式 一般来说这是可能的,但不是很容易 XLS文件格式由HSSFWorkbook类处理(并根据HSSFSheet等)。 XLSX文件格式由XSSFWorkbook类(以及X

我有一个*.xlsx格式的excel文件。我想在我的MVC Web应用程序中将此文件转换为*.xls格式。在我的应用程序托管服务器中,没有Microsoft.Office软件包。请让我知道我们如何用c#在NPOI中实现它

提前谢谢。

这是我的建议:

  • 使用此库可以读取格式为2007的excel文件

  • 使用此库可将文件另存为2003格式


一般来说这是可能的,但不是很容易

XLS
文件格式由
HSSFWorkbook
类处理(并根据
HSSFSheet
等)。
XLSX
文件格式由
XSSFWorkbook
类(以及
XSSFSheet
等)处理

因此,要将文件从
XLSX
转换为
XLS
,您需要:

  • 创建
    XSSFWorkbook
    ,将数据从文件加载到其中
  • 创建新的
    HSSFWorkbook
  • 对于原始文件中的每个工作表,创建
    HSSFSheet
    ,并将原始工作表中的所有数据复制到此新工作表中
  • 将您的
    HSSFWorkbook
    写入文件
所以这里有很多工作要做,这是一项非常复杂的任务


可能NPOI不是您的最佳解决方案。

我根据安迪的建议找到了解决方案。下面是定制的将XLSX转换为XLS的源代码

 public static class ConvertXLSXToXLS
{
    public static HSSFWorkbook ConvertWorkbookXSSFToHSSF(XSSFWorkbook source)
    {
        //Install-Package NPOI -Version 2.0.6
        HSSFWorkbook retVal = new HSSFWorkbook();
        for (int i = 0; i < source.NumberOfSheets; i++)
        {
            HSSFSheet hssfSheet = (HSSFSheet)retVal.CreateSheet(source.GetSheetAt(i).SheetName);

            XSSFSheet xssfsheet = (XSSFSheet)source.GetSheetAt(i);
            CopySheets(xssfsheet, hssfSheet, retVal);
        }
        return retVal;
    }

    private static void CopySheets(XSSFSheet source, HSSFSheet destination, HSSFWorkbook retVal)
    {
        int maxColumnNum = 0;
        Dictionary<int, XSSFCellStyle> styleMap = new Dictionary<int, XSSFCellStyle>();
        for (int i = source.FirstRowNum; i <= source.LastRowNum; i++)
        {
            XSSFRow srcRow = (XSSFRow)source.GetRow(i);
            HSSFRow destRow = (HSSFRow)destination.CreateRow(i);
            if (srcRow != null)
            {
                CopyRow(source, destination, srcRow, destRow, styleMap, retVal);
                if (srcRow.LastCellNum > maxColumnNum)
                {
                    maxColumnNum = srcRow.LastCellNum;
                }
            }
        }
        for (int i = 0; i <= maxColumnNum; i++)
        {
            destination.SetColumnWidth(i, source.GetColumnWidth(i));
        }
    }

    private static void CopyRow(XSSFSheet srcSheet, HSSFSheet destSheet, XSSFRow srcRow, HSSFRow destRow,
            Dictionary<int, XSSFCellStyle> styleMap, HSSFWorkbook retVal)
    {
        // manage a list of merged zone in order to not insert two times a
        // merged zone
        List<CellRangeAddress> mergedRegions = new List<CellRangeAddress>();
        destRow.Height = srcRow.Height;
        // pour chaque row
        for (int j = srcRow.FirstCellNum; j <= srcRow.LastCellNum; j++)
        {
            XSSFCell oldCell = (XSSFCell)srcRow.GetCell(j); // ancienne cell
            HSSFCell newCell = (HSSFCell)destRow.GetCell(j); // new cell
            if (oldCell != null)
            {
                if (newCell == null)
                {
                    newCell = (HSSFCell)destRow.CreateCell(j);
                }
                // copy chaque cell
                CopyCell(oldCell, newCell, styleMap, retVal);
                // copy les informations de fusion entre les cellules
                CellRangeAddress mergedRegion = GetMergedRegion(srcSheet, srcRow.RowNum,
                        (short)oldCell.ColumnIndex);

                if (mergedRegion != null)
                {
                    CellRangeAddress newMergedRegion = new CellRangeAddress(mergedRegion.FirstRow,
                            mergedRegion.LastRow, mergedRegion.FirstColumn, mergedRegion.LastColumn);
                    if (IsNewMergedRegion(newMergedRegion, mergedRegions))
                    {
                        mergedRegions.Add(newMergedRegion);
                        destSheet.AddMergedRegion(newMergedRegion);
                    }

                    if (newMergedRegion.FirstColumn == 0 && newMergedRegion.LastColumn == 6 && newMergedRegion.FirstRow == newMergedRegion.LastRow)
                    {
                        HSSFCellStyle style2 = (HSSFCellStyle)retVal.CreateCellStyle();
                        style2.VerticalAlignment = VerticalAlignment.Center;
                        style2.Alignment = HorizontalAlignment.Left;
                        style2.FillForegroundColor = HSSFColor.Teal.Index;
                        style2.FillPattern = FillPattern.SolidForeground;

                        for (int i = destRow.FirstCellNum; i <= destRow.LastCellNum; i++)
                        {
                            if (destRow.GetCell(i) != null)
                                destRow.GetCell(i).CellStyle = style2;
                        }
                    }
                }
            }
        }



    }

    private static void CopyCell(XSSFCell oldCell, HSSFCell newCell, Dictionary<int, XSSFCellStyle> styleMap, HSSFWorkbook retVal)
    {
        if (styleMap != null)
        {
            int stHashCode = oldCell.CellStyle.Index;
            XSSFCellStyle sourceCellStyle = null;
            if (styleMap.TryGetValue(stHashCode, out sourceCellStyle)) { }

            HSSFCellStyle destnCellStyle = (HSSFCellStyle)newCell.CellStyle;
            if (sourceCellStyle == null)
            {
                sourceCellStyle = (XSSFCellStyle)oldCell.Sheet.Workbook.CreateCellStyle();
            }
            // destnCellStyle.CloneStyleFrom(oldCell.CellStyle);
            if (!styleMap.Any(p => p.Key == stHashCode))
            {
                styleMap.Add(stHashCode, sourceCellStyle);
            }

            destnCellStyle.VerticalAlignment = VerticalAlignment.Top;
            newCell.CellStyle = (HSSFCellStyle)destnCellStyle;
        }
        switch (oldCell.CellType)
        {
            case CellType.String:
                newCell.SetCellValue(oldCell.StringCellValue);
                break;
            case CellType.Numeric:
                newCell.SetCellValue(oldCell.NumericCellValue);
                break;
            case CellType.Blank:
                newCell.SetCellType(CellType.Blank);
                break;
            case CellType.Boolean:
                newCell.SetCellValue(oldCell.BooleanCellValue);
                break;
            case CellType.Error:
                newCell.SetCellErrorValue(oldCell.ErrorCellValue);
                break;
            case CellType.Formula:
                newCell.SetCellFormula(oldCell.CellFormula);
                break;
            default:
                break;
        }

    }


    private static CellRangeAddress GetMergedRegion(XSSFSheet sheet, int rowNum, short cellNum)
    {
        for (int i = 0; i < sheet.NumMergedRegions; i++)
        {
            CellRangeAddress merged = sheet.GetMergedRegion(i);
            if (merged.IsInRange(rowNum, cellNum))
            {
                return merged;
            }
        }
        return null;
    }

    private static bool IsNewMergedRegion(CellRangeAddress newMergedRegion,
            List<CellRangeAddress> mergedRegions)
    {
        return !mergedRegions.Contains(newMergedRegion);
    }
}
公共静态类ConvertXLSXToXLS
{
公共静态HSSF工作簿转换器工作簿XSSFTOHSSF(XSSF工作簿源)
{
//安装程序包NPOI-版本2.0.6
HSSFWorkbook retVal=新的HSSFWorkbook();
对于(int i=0;i对于(inti=0;我有一个好主意,Andy,我将尝试以这种方式实现。正如Andy所说,我遵循了这个解决方案,只是将此代码转换为C#它对我来说很好。