简体   繁体   中英

Merge cells in excel sheet using Openxml sdk

I am using OpenXML sdk to export data from a list to excel sheet. I want to merge 10 rows below last row after the data is finished.

string templatePath = Server.MapPath("~/Content/Reports/Formate/someReport.xlsx");
string download_file_name = "Some__Report_" + Guid.NewGuid().ToString() + ".xlsx";
string newFilePath = Server.MapPath("~/Content/Reports/TempData/" + download_file_name);

System.IO.File.Copy(templatePath, newFilePath, true);

SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(newFilePath, true);
var sheet = spreadsheetDocument.WorkbookPart.Workbook
            .Sheets.Elements<Sheet>()
            .FirstOrDefault();

var sheetReferenceId = sheet.Id;

// Map the Id to the worksheet part
WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(sheetReferenceId);
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
uint rowNumber = 12;
string[] cellReferences = { "A", "B", "C", "D", "E" };

foreach (var item in someList)
{
    var row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowNumber).FirstOrDefault();

    if (row == null)
    {
        row = new Row();
        row.RowIndex = rowNumber;
        sheetData.Append(row);
    }

    if (row != null)
    {
        for (int j = 0; j < cellReferences.Length; j++)
        {
            string cellReference = cellReferences[j] + rowNumber.ToString();

            // Find cell in row
            var cell = row.Elements<Cell>()
                .Where(c => c.CellReference == cellReference)
                .FirstOrDefault();

            if (cell == null)
            {
                cell = new Cell();
                cell.CellReference = cellReference;
                row.InsertAt(cell, j);
            }

            if (cell != null)
            {
                switch (cellReferences[j])
                {
                    case "A":

                        cell.CellValue = new CellValue(item.AssignDate.ToString());
                        cell.DataType = new EnumValue<CellValues>(CellValues.String);
                        break;
                    case "B":
                        cell.CellValue = new CellValue(item.AssetTypeName);
                        cell.DataType = new EnumValue<CellValues>(CellValues.String);
                        break;
                    case "C":
                        cell.CellValue = new CellValue(item.Model);
                        cell.DataType = new EnumValue<CellValues>(CellValues.String);
                        break;
                    case "D":
                        cell.CellValue = new CellValue(item.SubscriberNo.ToString());
                        cell.DataType = new EnumValue<CellValues>(CellValues.String);
                        break;
                    case "E":
                        cell.CellValue = new CellValue(item.IMEI);
                        cell.DataType = new EnumValue<CellValues>(CellValues.String);
                        break;

                }
            }
        }

        rowNumber++;
    }
}

//I want here to merge 10 rows below rowNumber

spreadsheetDocument.Close();
//string download_path = string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~")) + "/Content/Reports/TempData/" + download_file_name;
this.Response.ClearContent();
this.Response.Clear();
this.Response.AddHeader("Content-Disposition", "attachment; filename=Assets_Report_" + DateTime.Now.ToShortDateString().Replace('/', '-') + ".xlsx");
this.Response.ContentType = "application/vnd.ms-excel.12";
this.Response.TransmitFile(newFilePath);
this.Response.Flush();
this.Response.End();

I have tried the solution Create Merge Cells using OpenXML but it did not worked for me. What I did was:

Row firstRow = new Row();
firstRow.RowIndex = (UInt32)rowNumber+1;

//create a cell in C1 (the upper left most cell of the merged cells)
Cell dataCell = new Cell();
dataCell.CellReference = "A" + firstRow.RowIndex.ToString(); ;
CellValue cellValue = new CellValue();
cellValue.Text = "";
dataCell.Append(cellValue);

firstRow.AppendChild(dataCell);

sheetData.AppendChild(firstRow);
// Add a WorkbookPart to the document.
worksheetPart.Worksheet = new Worksheet(sheetData);

//create a MergeCells class to hold each MergeCell
MergeCells mergeCells = new MergeCells();

//append a MergeCell to the mergeCells for each set of merged cells
mergeCells.Append(new MergeCell() { Reference = new StringValue(""+dataCell.CellReference+":F"+(firstRow.RowIndex+10)) });

worksheetPart.Worksheet.InsertAfter(mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());

//this is the part that was missing from your code
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet()
{
    Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(spreadsheetDocument.WorkbookPart.WorksheetParts.First()),
    SheetId = 1,
    Name = "Sheet1"
});

I am getting exception here Cannot insert the OpenXmlElement “newChild” because it is part of a tree.

I have tried the solution to Create Merge Cells using OpenXML but it did not worked for me.

That's because that solution is creating a new file from scratch but you are editing an existing file. You don't need the parts of that code that are creating Worksheets and Sheets etc. You just need the merge cell code:

Row firstRow = new Row();
firstRow.RowIndex = (UInt32)rowNumber + 1;

//create a cell in C1 (the upper left most cell of the merged cells)
Cell dataCell = new Cell();
dataCell.CellReference = "A" + firstRow.RowIndex.ToString(); ;
CellValue cellValue = new CellValue();
cellValue.Text = "";
dataCell.Append(cellValue);

firstRow.AppendChild(dataCell);

sheetData.AppendChild(firstRow);

//create a MergeCells class to hold each MergeCell
MergeCells mergeCells = new MergeCells();

//append a MergeCell to the mergeCells for each set of merged cells
mergeCells.Append(new MergeCell() { Reference = new StringValue("" + dataCell.CellReference + ":F" + (firstRow.RowIndex + 10)) });

worksheetPart.Worksheet.InsertAfter(mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM