Excel Open错误:创建Excel时“发现不可读的内容”

时间:2018-12-24 11:06:50

标签: c# excel spreadsheet openxml

我收到错误消息“ Excel在APPL_1.xlsx中发现了不可读的内容。” 我的代码有什么问题?。

记录包含大约2个缺少数据。我正在尝试将其从数据表中提取到excel。

我正在使用OpenXMLSpreedsheetDocument将数据从数据表中提取到excel

            FileInfo FileLoc = new FileInfo(FilePath);
            if (FileLoc.Exists)
            {
                FileLoc.Delete();
                FileLoc = new FileInfo(FilePath);
            }
            SpreadsheetDocument spreadSheet = SpreadsheetDocument.
            Create(FilePath, SpreadsheetDocumentType.Workbook);

            // Add a WorkbookPart to the document.
            WorkbookPart workbookpart = spreadSheet.AddWorkbookPart();
            workbookpart.Workbook = new Workbook();

            // Add a WorksheetPart to the WorkbookPart.
            var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
            var sheetData = new SheetData();
            worksheetPart.Worksheet = new Worksheet(sheetData);

            var bold1 = new Bold();
            CellFormat cf = new CellFormat();

            // Add Sheets to the Workbook.
            Sheets sheets;
            sheets = spreadSheet.WorkbookPart.Workbook.
                AppendChild<Sheets>(new Sheets());

            // Append a new worksheet and associate it with the workbook.
            var sheet = new Sheet()
            {
                Id = spreadSheet.WorkbookPart.
                    GetIdOfPart(worksheetPart),
                SheetId = 0,
                Name = "Sheet" + 0
            };
            sheets.Append(sheet);

            //Add Header Row.
            var headerRow = new Row();
            foreach (DataColumn column in dt.Columns)
            {
                var cell = new Cell
                {
                    DataType = CellValues.String,
                    CellValue = new CellValue(column.ColumnName)
                };
                headerRow.AppendChild(cell);
            }
            sheetData.AppendChild(headerRow);
            foreach (DataRow row in dt.Rows)
            {
                var newRow = new Row();
                foreach (DataColumn col in dt.Columns)
                {
                    Cell c = new Cell();
                    c.DataType = new EnumValue<CellValues>(CellValues.String);
                    c.CellValue = new CellValue(row[col].ToString());
                    newRow.Append(c);
                }
                sheetData.AppendChild(newRow);
            }
            workbookpart.Workbook.Save();
            ProcessStartInfo startInfo = new ProcessStartInfo(FilePath);
            Process.Start(startInfo);  

任何建议都非常感激.. !!

2 个答案:

答案 0 :(得分:0)

这是我对OpenXML的实现。为简单起见,我已排除了单元样式代码。

这将创建一个包含两行三列的excel文件。您可以根据自己的需要进行修改。

主要方法:

static void Main(string[] args)
{
    var dtToXl = new DtToExcel();
    var dt = new DataTable();
    dt.Columns.Add("Col1");
    dt.Columns.Add("Col2");
    dt.Columns.Add("Col3");
    dt.Rows.Add("R1C1", "R1C2", "R1C3");
    dt.Rows.Add("R2C1", "R2C2", "R2C3");

    dtToXl.GetExcel(dt);
    if(Debugger.IsAttached)
    {
        Console.ReadLine();
    }
}

GetExcel方法:

public void GetExcel(DataTable dt)
{
    using (var document = SpreadsheetDocument.Create("C:\\Desktop\\Excel1.xlsx", SpreadsheetDocumentType.Workbook))
    {
        var workbookPart = document.AddWorkbookPart();
        workbookPart.Workbook = new Workbook();
        var sheets = workbookPart.Workbook.AppendChild(new Sheets());
        AddWorksheet(dt, 1, ref sheets, ref workbookPart);
    }
}

AddWorksheet方法:

private void AddWorksheet(DataTable dt, int sheetCount, ref Sheets sheets, ref WorkbookPart workbookPart)
{
    var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    var sheetData = new SheetData();
    var sheetName = $"Sheet{sheetCount}";
    worksheetPart.Worksheet = new Worksheet();

    //Create header rows
    #region Excel Headers
    Row row = new Row
    {
        RowIndex = 1
    };
    row.AppendChild(AddCellWithValue("Column 1", CellValues.InlineString));
    row.AppendChild(AddCellWithValue("Column 2", CellValues.InlineString));
    row.AppendChild(AddCellWithValue("Column 3", CellValues.InlineString));
    sheetData.AppendChild(row);
    #endregion

    //Create data rows
    #region Excel data rows
    var rowIndex = (UInt32)2;
    foreach (DataRow dtRow in dt.Rows)
    {
        row = new Row
        {
            RowIndex = rowIndex++
        };
        row.AppendChild(AddCellWithValue(dtRow[0].ToString(), CellValues.InlineString));
        row.AppendChild(AddCellWithValue(dtRow[1].ToString(), CellValues.InlineString));
        row.AppendChild(AddCellWithValue(dtRow[2].ToString(), CellValues.InlineString));
        sheetData.AppendChild(row);
    }
    #endregion

    var columns = new Columns();
    columns.Append(new Column() { Min = 1, Max = 1, Width = 20, CustomWidth = true });
    columns.Append(new Column() { Min = 2, Max = 2, Width = 20, CustomWidth = true });
    columns.Append(new Column() { Min = 3, Max = 3, Width = 20, CustomWidth = true });

    worksheetPart.Worksheet.Append(columns);
    worksheetPart.Worksheet.Append(sheetData); //This line should be anywhere below .Append(columns)

    var sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = (UInt32)sheetCount, Name = sheetName };
    sheets.Append(sheet);
}

AddCellWithValue方法

private Cell AddCellWithValue(string value, CellValues type)
{
    var cell = new Cell
    {
        DataType = type
    };
    if (type == CellValues.InlineString)
    {
        var inlineString = new InlineString();
        var t = new Text
        {
            Text = value
        };
        inlineString.AppendChild(t);
        cell.AppendChild(inlineString);
    }
    else
    {
        cell.CellValue = new CellValue(value);
    }
    return cell;
}

答案 1 :(得分:0)

我已经使用了SpreadsheetLight。

这是我的代码。

            using SpreadsheetLight;

            SLDocument sl = new SLDocument();

            int iStartRowIndex = 1;
            int iStartColumnIndex = 1;

            sl.ImportDataTable(iStartRowIndex, iStartColumnIndex, dt, true);

            // + 1 because the header row is included
            // - 1 because it's a counting thing, because the start row is counted.
            int iEndRowIndex = iStartRowIndex + dt.Rows.Count + 1 - 1;
            // - 1 because it's a counting thing, because the start column is counted.
            int iEndColumnIndex = iStartColumnIndex + dt.Columns.Count - 1;

            SLTable table = sl.CreateTable(iStartRowIndex, iStartColumnIndex, iEndRowIndex, iEndColumnIndex);
            table.SetTableStyle(SLTableStyleTypeValues.Medium17);
            table.HasTotalRow = true;
            table.SetTotalRowFunction(5, SLTotalsRowFunctionValues.Sum);
            sl.InsertTable(table);

            sl.SaveAs(FilePath);
            sl.Dispose();
            ProcessStartInfo startInfo = new ProcessStartInfo(FilePath);
            Process.Start(startInfo);