Copying sheet to another Excel workbook using C# and OpenXML - c#

Sheet 2 contains the lists which are created previously, and sheet 1 contains the links to sheet 2, so when I generate sheet 1, I want sheet 2 to be copied to the workbook.
static void CopySheet(string filename, string sheetName, string clonedSheetName) {
//Add new sheet to main workbook part
Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
Sheet copiedSheet = new Sheet();
copiedSheet.Name = clonedSheetName;
copiedSheet.Id = workbookPart.GetIdOfPart(clonedSheet);
copiedSheet.SheetId = (uint)sheets.ChildElements.Count + 1;
sheets.Append(copiedSheet);
//Save Changes
workbookPart.Workbook.Save();
}

Try
using (ExcelPackage ExcelFile = new ExcelPackage(new System.IO.FileInfo(#"C:\temp\MyExcelFile.xlsx")))
{
ExcelFile.Workbook.Worksheets.Copy("SheetToCopyName", "SheetToCopyToName");
}
This is done with EPPlus which uses OpenXML library. If you're using another library let me know.

Related

Open XML Creating Multiple sheets

I am trying to create an Excel file using Open XML C#, where there are multiple sheets in my excel file that needs to be created. Please find my code below and help me with a solution.
When I open the excel only 1 sheet is present, sheet 2 is getting overwritten in sheet 1.
public void CreateExcelFile(string filePath , List<SheetData> excelSheet)
{
var sheetCount = GetSheetCount(filePath);
using (SpreadsheetDocument spreedDoc = SpreadsheetDocument.Create(filePath,
DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
Workbook workbook1 = new Workbook();
workbook1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
FileVersion fileVersion1 = new FileVersion() { ApplicationName = "xl", LastEdited = "5", LowestEdited = "4", BuildVersion = "9302" };
WorkbookProperties workbookProperties1 = new WorkbookProperties() { FilterPrivacy = true, DefaultThemeVersion = (UInt32Value)124226U };
BookViews bookViews1 = new BookViews();
WorkbookView workbookView1 = new WorkbookView() { XWindow = 240, YWindow = 105, WindowWidth = (UInt32Value)14805U, WindowHeight = (UInt32Value)8010U, ActiveTab = (UInt32Value)2U };
bookViews1.Append(workbookView1);
Sheets sheetCol = new Sheets();
int ctr = 0;
foreach (var sheetToCreate in excelSheet)
{
ctr++;
//WorksheetPart worksheetPart = null;
//worksheetPart = wbPart.AddNewPart<WorksheetPart>();
//var sheetData = new SheetData();
//worksheetPart.Worksheet = new Worksheet(sheetData);
//worksheetPart.Worksheet = new Worksheet(sheetToCreate);
string sheetName = "Sheet";
sheetName += ctr.ToString();
var sheet = new Sheet()
{
Id = "rId" + ctr,
SheetId = (UInt32)ctr,
Name = sheetName
};
sheet.Append(sheetToCreate);
sheetCol.Append(sheet);
//wbPart.Workbook.Sheets.AppendChild(sheet);
//wbPart.Workbook.Append(sheetCol);
workbook1.Sheets.Append(sheet);
//var workingSheet = ((WorksheetPart)wbPart.GetPartById(sheet.Id)).Worksheet;
}
workbook1.Append(fileVersion1);
workbook1.Append(workbookProperties1);
workbook1.Append(bookViews1);
workbook1.Append(sheetCol);
//Set Border
//wbPark
workbook1.Save();
}
}
When dealing with OpenXML, the "OpenXML Productivity Tool" (downloadable from Microsoft's site) is your friend. When I work with creating documents with OpenXML, I do the following:
Create a document similar to what I want using Excel or Word (in this case, an Excel spreadsheet document with two sheets (I labeled them "First" and "Second")).
Open the document up in the productivity tool
Reflect the code (a button on the Tool's UI)
Copy/paste the code I want.
If I do that, I end up with all the code I need. I've boiled it down to the essentials to answer your question. Excel will complain that the document produced below is corrupt (since all it includes is the code to create the two sheets - and leaves lots of other required code out - all of which is stealable from the tool). However, if you tell Excel "Repair this for me", you will get a document with two sheets, labeled "First" and "Second"
WorkbookPart workbookPart1 = document.AddWorkbookPart();
Workbook workbook1 = new Workbook() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x15 xr xr6 xr10 xr2" } };
//lots of namespace declarations - copy them from the tool (they are needed!!)
//lots of code for WorkbookProperties, etc (you can get this from Tool)
Sheets sheets1 = new Sheets();
Sheet sheet1 = new Sheet() { Name = "First", SheetId = (UInt32Value)1U, Id = "rId1" };
Sheet sheet2 = new Sheet() { Name = "Second", SheetId = (UInt32Value)2U, Id = "rId2" };
sheets1.Append(sheet1);
sheets1.Append(sheet2);
//More elided code
workbook1.Append(sheets1);
workbookPart1.Workbook = workbook1;
I strongly recommend that you keep the pluralization of things like Sheet and Sheets clear. Your code has Sheets sheetCol = new Sheets();, it's not clear after that that sheetCol is a Sheets and not a Sheet.
Then you have something called sheetToCreate which is a SheetData object. Again, that's confusing - call it something clear like thisSheetData or something. I really strongly recommend that you follow the OpenXML naming as much as you can, otherwise it is extremely hard to follow what's going on.
The Productivity Tool is also handy once you've written out your file. You can see what you created, often spotting what the error is. In addition, there's a validate button that usually (not always) points you to problems in the structure of your documents.
Good luck. Prepare to get better at cussing at your code!

Programmatically sort Excel spreadsheets

I am using OpenXML to manipulate Excel files.
I am sending the Excel files as memory stream, editing them and then send them back to browser so they open in client office program. I create new spread sheet by using this code:
public static void InsertWorksheet(string docName)
{
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
{
// Add a blank WorksheetPart.
WorksheetPart newWorksheetPart = spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart);
// Get a unique ID for the new worksheet.
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
// Give the new worksheet a name.
string sheetName = "Sheet" + sheetId;
// Append the new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
sheets.Append(sheet);
}
}
My problem is that this sheet is added last among the sheets in the workbook. I want it to be sheet nr 1. I am looking for tips on how I can set my newly created sheet to be sheet nr. 1.
Maybe instead of sheets.Append you call something that inserts it at the beginning? is there a Insert or Prepend method?

Convert XLSX to PDF on one page by Spire.Pdf (c#)

I have one page XLSX work sheet (invoice). I need to convert it to one page PDF document. For it I am using Spire library. But it covert my document to two pages.
Code:
using (ExcelPackage xlPackageRef = new ExcelPackage(totalXlsFile))
{
using (ExcelPackage xlPackage = new ExcelPackage(workXlsFile))
{
ExcelWorkbook wb = xlPackage.Workbook;
ExcelWorkbook wbRef = xlPackageRef.Workbook;
var sheetName = invoice.XlsSeznamFakturNazevListu;
OfficeOpenXml.ExcelWorksheet wsRef = wbRef.Worksheets[sheetName];
if (wsRef != null)
{
// create xls work file
wb.Worksheets.Add("faktura", wsRef);
xlPackage.Save();
// load Excel file
Workbook workbook = new Workbook();
workbook.LoadFromFile(workXlsFilePath);
// pdf file path
FileInfo pdfInvoiceFile = new FileInfo(pdfInvoiceTargetFolder + #"/" + pdfInvoiceFileName);
if (pdfInvoiceFile.Exists)
pdfInvoiceFile.Delete();
// create pdf file
workbook.SaveToFile(pdfInvoiceFile.FullName, Spire.Xls.FileFormat.PDF);
}
}
}
First, I suppose you were using Spire.XLS rather than Spire.PDF.
Second, you need to do some page setup before converting. Try below code:
Worksheet worksheet = workbook.Worksheets[index];
PageSetup setup = worksheet.PageSetup;
setup.FitToPagesWide = 1;
setup.FitToPagesTall = 1;

The process cannot access the file because it is being used by another process using spreadsheet document

Please help me to solve the problem, when i save the excel file throw this error i convert the excel file to zip file.
zip.Save(#"" + root + "/" + "" + userid + ".zip");
the process cannot access the file because it is being used by another process
my code is below
using (SpreadsheetDocument document = SpreadsheetDocument.Create(excelFilename, SpreadsheetDocumentType.Workbook))
{
WriteExcelFile(ds, document);
}
private static void WriteExcelFile(DataSet ds, SpreadsheetDocument spreadsheet)
{
spreadsheet.AddWorkbookPart();
spreadsheet.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
spreadsheet.WorkbookPart.Workbook.Append(new BookViews(new WorkbookView()));
// If we don't add a "WorkbookStylesPart", OLEDB will refuse to connect to this .xlsx file !
WorkbookStylesPart workbookStylesPart = spreadsheet.WorkbookPart.AddNewPart<WorkbookStylesPart>("rIdStyles");
Stylesheet stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet = stylesheet;
// Loop through each of the DataTables in our DataSet, and create a new Excel Worksheet for each.
uint worksheetNumber = 1;
foreach (DataTable dt in ds.Tables)
{
// For each worksheet you want to create
string workSheetID = "rId" + worksheetNumber.ToString();
string worksheetName = dt.TableName;
WorksheetPart newWorksheetPart = spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet();
// create sheet data
newWorksheetPart.Worksheet.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.SheetData());
// save worksheet
WriteDataTableToExcelWorksheet(dt, newWorksheetPart);
newWorksheetPart.Worksheet.Save();
// create the worksheet to workbook relation
if (worksheetNumber == 1)
spreadsheet.WorkbookPart.Workbook.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.Sheets());
spreadsheet.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>().AppendChild(new DocumentFormat.OpenXml.Spreadsheet.Sheet()
{
Id = spreadsheet.WorkbookPart.GetIdOfPart(newWorksheetPart),
SheetId = (uint)worksheetNumber,
Name = dt.TableName
});
worksheetNumber++;
}
spreadsheet.WorkbookPart.Workbook.Save();
}
I see that you have saved your document but you have not closed it. So, it will still be open with the spreadsheetdocument object.
Add the following line after you save the document.
spreadsheet.WorkbookPart.Workbook.Close();
If it doesn't help, kindly provide the full code so that we can look into it further. Good luck.
I think you are not closing all your Workbooks before you try to put them in the Zip-File.
Put this at the end of the Method:
private static void WriteExcelFile(DataSet ds, SpreadsheetDocument spreadsheet)
{
...
spreadsheet.WorkbookPart.Workbook.Close();
}

opening .xlsx in office 2003

I have created a .xlsx using openxml.
I am not able to open this file in office 2003.. I have also tried using compatibility pack but still the file does not open. What can be done if i need to generate .xlsx that can be opened in office 2003 as well.
Code i am using to generate .xlsx is :
public static void HelloWorldXlsx(string docName)
{
SpreadsheetDocument package = SpreadsheetDocument.Create(docName, SpreadsheetDocumentType.Workbook);
package.AddWorkbookPart();
package.WorkbookPart.Workbook = new Workbook();
WorksheetPart wspart = package.WorkbookPart.AddNewPart<WorksheetPart>();
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new DocumentFormat.OpenXml.Spreadsheet.Text("Hello World!"));
wspart.Worksheet = new Worksheet(new SheetData(new Row(cell)));
wspart.Worksheet.Save();
package.WorkbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet();
sheet.Id = package.WorkbookPart.GetIdOfPart(wspart);
sheet.SheetId = 1;
sheet.Name = "Hello !";
package.WorkbookPart.Workbook.GetFirstChild<Sheets>().AppendChild<Sheet>(sheet);
package.WorkbookPart.Workbook.Save();
package.Close();
}
Thanks for suggestion. I got the answer to my question .. I had not set cellReference property of Cell in my code.

Categories