Last active
June 24, 2021 01:08
-
-
Save josephmate/d46f2fcca8088c1a4bcec3d2fe62cd2a to your computer and use it in GitHub Desktop.
fixed when replacing existing rows. previously only appending worked.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text.RegularExpressions; | |
using DocumentFormat.OpenXml; | |
using DocumentFormat.OpenXml.Packaging; | |
using DocumentFormat.OpenXml.Spreadsheet; | |
namespace CopyRowOpenXML | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// backup the file incase we corrupt the file | |
string fromFile = "C:\\Users\\Joseph\\Desktop\\sample.xlsx"; | |
string toFile = "C:\\Users\\Joseph\\Desktop\\sampleResult.xlsx"; | |
if(System.IO.File.Exists(toFile)){ | |
System.IO.File.Delete(toFile); | |
} | |
System.IO.File.Copy(fromFile, toFile); | |
// modify the backup | |
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(toFile, true)) | |
{ | |
CopyRowsAndReplace(spreadsheetDocument, "Sheet1", 3, 5, 7); | |
spreadsheetDocument.Save(); | |
} | |
Console.WriteLine("Done"); | |
} | |
/// <summary> | |
/// Copies the rows in the document using the rows starting from 'srcRowFrom' until 'srcRowTo' (inclusive) and places them starting at 'destRowFrom'. | |
/// If there is data already in those rows, it will be overwritten. | |
/// </summary> | |
/// <param name="document">The document to take the rows from</param> | |
/// <param name="sheetName">The name of the sheet in the 'document' to take the rows from</param> | |
/// <param name="srcRowFrom">The index of the row to start copying from</param> | |
/// <param name="srcRowTo">The index of the final row to copy</param> | |
/// <param name="destRowFrom">Where to start placing the copied rows</param> | |
public static void CopyRowsAndReplace(SpreadsheetDocument document, string sheetName, | |
int srcRowFrom, int srcRowTo, int destRowFrom) | |
{ | |
WorkbookPart workbookPart = document.WorkbookPart; | |
if (srcRowTo < srcRowFrom || destRowFrom < srcRowFrom) return; | |
int destRowFromBase = destRowFrom; | |
WorksheetPart worksheetPart = GetWorksheetPartByName(document, sheetName); | |
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>(); | |
// 1. Delete the existing rows if any are present. | |
int destRowTo = destRowFrom + (srcRowTo - srcRowFrom); | |
IList<Row> rowsToDelete = sheetData.Descendants<Row>() | |
.Where(r => r.RowIndex >= destRowFrom && r.RowIndex <= destRowTo) | |
.ToList<Row>(); | |
foreach(Row row in rowsToDelete) | |
{ | |
row.RemoveAllChildren(); | |
} | |
// 2. Copy the rows | |
IList<Row> rowsToCopy = sheetData.Descendants<Row>() | |
.Where(r => r.RowIndex >= srcRowFrom && r.RowIndex <= srcRowTo) | |
.ToList<Row>(); | |
int currentCopiedRow = destRowFrom; | |
foreach (Row row in rowsToCopy) | |
{ | |
Row copiedRow = new Row() { RowIndex = new UInt32Value(Convert.ToUInt32(currentCopiedRow)) }; | |
foreach(Cell cell in row.Elements<Cell>()) | |
{ | |
Cell copiedCell = new Cell() { | |
CellReference = new StringValue(GetColumnLetter(cell.CellReference.Value) + currentCopiedRow.ToString()) | |
}; | |
copiedCell.CellValue = new CellValue(cell.CellValue.Text); | |
copiedRow.Append(copiedCell); | |
} | |
sheetData.Append(copiedRow); | |
currentCopiedRow++; | |
} | |
} | |
private static WorksheetPart | |
GetWorksheetPartByName(SpreadsheetDocument document, | |
string sheetName) | |
{ | |
IEnumerable<Sheet> sheets = | |
document.WorkbookPart.Workbook.GetFirstChild<Sheets>(). | |
Elements<Sheet>().Where(s => s.Name == sheetName); | |
if (sheets.Count() == 0) | |
{ | |
return null; | |
} | |
string relationshipId = sheets.First().Id.Value; | |
WorksheetPart worksheetPart = (WorksheetPart) | |
document.WorkbookPart.GetPartById(relationshipId); | |
return worksheetPart; | |
} | |
private static string GetColumnLetter(string cellReference) | |
{ | |
Regex regex = new Regex("[A-Za-z]+"); | |
Match match = regex.Match(cellReference); | |
return match.Value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment