Unable To Open xlsm file in OpenXML SDK 2.0
edit and save excel file with macros on xlsm format (OpenXML SDK 2.0)
Hy,
I'm having a problem editing and saving xlsm files (with macros) programmatically. If I try to open the
generated file manually, i get a "File is Corrupted" error.
OpenXML SDK 2.5 with Visual Studio 2008
I am trying to use the OpenXML 2.5 with Visual Studio 2008, but have not been able to get it to work. I added the DocumentFormat.OpenXml and WindowBase as references to the project, but there is an exclamation mark over the DocumentFormat.OpenXml reference. When I double click it, it says "This project cannot be viewed in the object browser because it is unavailable or not yet built. Please ensure that the project is available and built".
When I try to use the library in the code with this line:
using DocumentFormat.OpenXml.Wordprocessing;
I get an error that the type or namespace could not be found.
SpreadsheetDocument not accepting memory stream from XLSM doc
Hi,<o:p></o:p>
SpreadsheetDocumentclass not accepting memory stream from XLSM doc.<o:p></o:p>
IF I pass memorystream of xlsx document, it doesn't through error message.<o:p></o:p>
using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(memstr,true))<o:p></o:p>
In the above line, i am getting "the specified package is invalid. the main part is missing" error message. while passing XLSM doc's mem stream.
Please let me know how to fix this issue.<o:p></o:p>
Bug: allocated Paragraph preventing file save
Hi all,
I just tried to make a simple program that replaces a text in a file; However, if I get a handle to a paragraph before doing the replacement, after the file is closed the content remains unchanged.
My code is as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.IO; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Wordprocessing; namespace MyAspControl { public partial class OpenXml : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string outputFile = @"C:\Users\asus\Desktop\dopo\Tenancy_Contract_C_20110922.docx"; File.Copy(TemplatePath, outputFile, true); using (WordprocessingDocument docx = WordprocessingDocument.Open(outputFile, true)) { //Commenting this line prevents the issue from occurring Paragraph p = docx.MainDocumentPart.Document.Body.Elements<Paragraph>().First(); string docText = null; using (StreamReader sr = new StreamReader(docx.MainDocumentPart.GetStream())) { docText = sr.ReadToEnd(); } docText = docText.Replace("[<[TND01]>]", "antani"); using (StreamWriter sw = new StreamWriter(docx.MainDocumentPart.GetStream(FileMode.Create))) { sw.Write(docText); } //After the document is closed the marker TND01 is still there docx.Close(); } } } }
If I comment line
Paragraph p = docx[....]
(the one that gets the pointer to the Paragraph) the replace and save work fine.
Michele
Paragraph identation attribute corrupted by sdk and yields invalid document.
I set the body.InnerXml directly, but our markup corrupted by the sdk.
If the original xml document contains
<w:pPr><w:ind w:left="288" /></w:pPr>
the sdk "convert" it to
<w:pPr><w:ind w:start="288" /></w:pPr>
This is incorrect according the schema specification. How can we prevent this?
Copying a worksheet in OpenXML that has previously been modified
I have followed the routine used here to copy a worksheet in a workbook into the same workbook by using .AddPart<>() and a temporary workbook to serve as a middleman, but have come up with some issues. Prior to copying the worksheet, I have made modifications to it. However, the copied version of the worksheet retains the original sheet, not the modified one. Here's the code:
Document = SpreadsheetDocument.Open(filename, true); SetupPages(0, nSections); CopySheet(1);
SetupPages() simply gets a worksheet which has a table with only one row and then copies that row (nSections - 1) times, so that the table ends up with (nSections) rows. This seems to work (the sheets which correspond to p = 0 are correctly modified). However, in case the problem is with the binding of these new rows to the SheetData (or something, here's the code for SetupPages():
public void SetupPages(int p, int nSections) { Regex rn = new Regex("[0-9]+"); Regex rs = new Regex("[A-Z]+"); SheetData sData = Document.XGet<SheetData>(2 * p + 1); for (uint i = 1; i < nSections; i++) { var r = sData.ChildElements.GetItem(4).Clone() as Row; r.RowIndex.Value += i; foreach (OpenXmlElement _c in r.ChildElements) { var c = _c as Cell; Match mn = rn.Match(c.CellReference.Value); Match ms = rs.Match(c.CellReference.Value); string str = (int.Parse(mn.Value) + i).ToString(); c.CellReference.Value = ms.Value + str; } (r.FirstChild as Cell).CellValue = new CellValue((i + 1).ToString()); sData.Append(r); } }
CopySheet() has the following code:
private void CopySheet(int sNum) { var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); var part = Document.XGetWorkSheetPart(sNum); WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); var sheets = Document.WorkbookPart.Workbook.GetFirstChild<Sheets>(); var sheet = new Sheet(); sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); sheet.Name = "AAA"; sheet.SheetId = (uint)sheets.ChildElements.Count + 1; sheets.Append(sheet); }
This method gets the desired workSheetPart and uses tempSheet.AddPart<>() to perform a deep copy of the desired part and then uses it again to deep copy it back into the original document. This way all the referenced objects contained within the desired workSheetPart are also copied.
This works, in as much as I now have a copy of the workSheet in my original document. However, all the modifications made by SetupPages() prior to calling CopySheet() do not appear in the copied workSheet. So I now have the original Sheet with (in this example) 11 rows and the copied Sheet with only 1 row. Interestingly enough, using the debugger I have noticed that part.WorkSheet.ChildElements.Count = 15 (the expected number of rows after SetupPages()). However, tempWBP.WorkSheet.ChildElements.Count = 5 (the number of rows in the original sheet prior to the modifications of SetupPages). For whatever reason, the new Rows added by my program are not being deep-copied. Now this I just don't understand.
I have tried placing a Document.WorkbookPart.WorkBook.Save() between SetupPages() and CopySheet(), to see if "saving the changes" would make them available to be copied as well, but to no avail.
I've been able to make the copy work fully, but it's very unelegant and doesn't fix what is clearly an error in the code, but merely an emergency measure to pretend that there isn't a problem. I basically get a clone of the original SheetData (which contains the modifications done in SetupPages()) and set it as the SheetData of the copied Sheet. I'm just posting this here for information purposes, but if someone could still please point out what is wrong in the code that I'm not seeing, I'll be quite thankful. Here's the "hacked" version of CopySheet(), if anyone is interested.
private void CopySheet(int sNum) { var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); var part = Document.XGetWorkSheetPart(sNum); var b = part.Worksheet.ChildElements[5].Clone() as SheetData; WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); copy.Worksheet.RemoveChild<SheetData>(copy.Worksheet.ChildElements[5] as SheetData); copy.Worksheet.InsertAt<SheetData>(b, 5); var sheets = Document.WorkbookPart.Workbook.GetFirstChild<Sheets>(); var sheet = new Sheet(); sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); sheet.Name = "AAA"; sheet.SheetId = (uint)sheets.ChildElements.Count + 1; sheets.Append(sheet); }
Is there any OpenXML trick I am unaware of to get rid of what is clearly wrong in my code?
installing Open SDK 2.0 with .net 4.0
I'm trying to install openxmlsdkv2 (with .net 4 working), and getting "The setup requires .net 3.5 sp1". what can i do ?
Error making more than one copy of a worksheet
I have a program which modifies an existing spreadsheet. Part of the program creates copies of certain sheets. To create one copy, the program runs perfectly and the resulting file is also fine, presenting no errors when opened in Excel. However, when creating two copies of the same worksheet, the program still runs just fine but, when opened in Excel, the following error appears regarding unreadable content:
Repaired Records: Worksheet properties from /xl/workbook.xml part (Workbook)
Here is the code used to perform the copy:
private void CopySheet(int sNum, int pNum, string type) { var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); var part = Document.XGetWorkSheetPart(sNum); var sheetData = part.Worksheet.ChildElements[5].Clone() as SheetData; var merge = part.Worksheet.ChildElements[6].Clone() as MergeCells; WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); //copy.Worksheet.RemoveChild<SheetData>(copy.Worksheet.ChildElements[5] as SheetData); //copy.Worksheet.InsertAt<SheetData>(sheetData, 5); //copy.Worksheet.RemoveChild<MergeCells>(copy.Worksheet.ChildElements[6] as MergeCells); //copy.Worksheet.InsertAt<MergeCells>(merge, 6); //copy.Worksheet.SheetProperties.CodeName.Value = "Phase" + pNum + type; var sheets = Document.WorkbookPart.Workbook.Sheets; var sheet = new Sheet(); sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); sheet.Name = "Phase " + pNum + " " + type; sheet.SheetId = (uint)sheets.ChildElements.Count; sheets.Append(sheet); }
(Document.XGetWorkSheetPart(int index) is an extension of SpreadsheetDocument which calls Document.WorkbookPart.GetPartById((doc.WorkbookPart.Workbook.Sheets.ChildElements.GetItem(index) as Sheet).Id) as WorksheetPart;)
This method makes use of the fact that .AddPart<>() performs a deep copy of any Part (and anything it references to) which does not already belong in the document to, with the help of a temporary sheet, create a deep copy of all referenced parts of a WorkSheet.
As stated above, this works quite well if the function is called only once for a given sheet. If it is called more than once, however, the file when opened in Excel gives an error of unreadable content. That being said, the file itself seems just fine, with no missing data or anything (which would help to figure out what exactly was wrong), just the error saying there was something wrong.
The lines that are commented out are a "hack" I had to do to deal with problems regarding .AddPart<>(), but I won't go into much detail with them here because I've already posted about this here (but I still haven't gotten a reply, so by all means, please answer that question, too!). That being said, those lines seem to have no relevance to this current problem since the error appears with or without those lines of code.
how to generate thumbnail form buildingblock?
"%appdata%\Microsoft\Document Building Blocks\2052\15\Built-In Building Blocks.dotx"
this office default template file has many useful buildingblocks, in word can take a look from UI command "insert->cover command"
now i have created a custom template file, is there any way to generate custom buildingblock to thumbnail for user selecting?
Query Regarding Support of OLE objects
Hi,
I have a migration tool that migrates data from Lotus Notes ECM. However i am not sure about Office Info Path 2010 that supports the creation of OLE objects or not. I just want to make sure if Info Path supports this feature(OLE Objects) , it would be helpful if i am provided with some links regarding this and if it does not support how can i proceed further with my OLE Objects that i have in Lotus Notes ECM and migrate those to Office Info Path.
Any comments/suggestions will help a lot.
Thanks in Advance.
Unable to open .docx created with OpenXML SDK 2.5 in Word 2007
Hi,
I use OpenXML SDK 2.5 to open and modify a .dotx template in c# and save it in .docx format. Most of our machines are able to open the resulting file with no difficulty, but I've discovered that those of us using Word 2007 (not 2010 or 2013) get an error message when they try to open the .docx file: "The file ____.docx cannot be opened because there are problems with the contents." The details further specify: "The file is corrupt and cannot be opened. Location: Part: /word/settings.xml, Line: 1, Column: 2668"
Below is a portion of my code (the part responsible for creating the .docx file):
File.Copy(sourceFile, destinationFile, true); using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true)){ // Change the document type to Document Documentdocument.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document); // Get the MainPart of the document MainDocumentPart mainPart = document.MainDocumentPart; // Get the Document Settings Part DocumentSettingsPart documentSettingPart1 = mainPart.DocumentSettingsPart; // Create a new attachedTemplate and specify a relationship ID AttachedTemplate attachedTemplate1 = new AttachedTemplate() { Id = "relationId1" }; // Append the attached template to the DocumentSettingsPart documentSettingPart1.Settings.Append(attachedTemplate1); // Add an ExternalRelationShip of type AttachedTemplate. // Specify the path of template and the relationship IDdocumentSettingPart1.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate", new Uri(sourceFile, UriKind.Absolute), "relationId1"); // Get a list of bookmarks IDictionary<String, BookmarkStart> bookmarkMap = new Dictionary<String, BookmarkStart>(); foreach (BookmarkStart bookmarkStart in mainPart.RootElement.Descendants<BookmarkStart>()) { bookmarkMap[bookmarkStart.Name] = bookmarkStart; } // Make changes to bookmarks foreach (BookmarkStart bookmarkStart in bookmarkMap.Values) { if (bookmarkStart.Name == "WorkOrderNo") { Text text = new Text(WorkOrderNum); FontSize WOFontSize = new FontSize(); WOFontSize.Val = "28"; Run run = new Run(new RunProperties(new Bold(), WOFontSize)); run.Append(text); bookmarkStart.InsertAfterSelf(run); } else if (bookmarkStart.Name == "BillingCode") { Text text = new Text(BillingCode); FontSize WOFontSize = new FontSize(); WOFontSize.Val = "28"; Run run = new Run(new RunProperties(new Bold(), WOFontSize)); run.Append(text); bookmarkStart.InsertAfterSelf(run); } } // Save the document mainPart.Document.Save();}
Word 2007 users are able to open the file if they choose "OK" on the prompt, and then "Yes" on the prompt reading: "Word found unreadable content in _____.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes." While this is an acceptable short-term workaround, I'm hoping to come up with a solution to the problem. Any ideas?
(I can send/attach the .dotx and .docx files if desired; I just couldn't figure out how to attach them to this post)
Thanks,
- Jim
Office open XML ( open XML) probelm with Mac OS
How can i check whether my application is generating Transitional OpenXML document or Strict OpenXML document ?
And how can i convert that into a Transitional OpenXML document ?
Please suggest me
Thanks
Pradeep Simhadri
Using OpenXML SDK via C++/CLI
I am trying to use the OpenXML SDK 2.5 via C++/CLI. Using the example code at the bottom of this MSDN page (http://msdn.microsoft.com/en-us/library/office/ff478153.aspx) works correctly when compiled with C# - I can open the created file successfully in Excel 2007.
The MSDN example code I translated to C++/CLI as follows:
void CreateSpreadsheetWorkbook(String^ filepath) { // Create a spreadsheet document by supplying the filepath. // By default, AutoSave = true, Editable = true, and Type = xlsx. SpreadsheetDocument^ spreadsheetDocument = SpreadsheetDocument::Create(filepath, SpreadsheetDocumentType::Workbook); // Add a WorkbookPart to the document. WorkbookPart^ workbookpart = spreadsheetDocument->AddWorkbookPart(); workbookpart->Workbook = gcnew Workbook(); // Add a WorksheetPart to the WorkbookPart. WorksheetPart^ worksheetPart = workbookpart->AddNewPart<WorksheetPart^>(); worksheetPart->Worksheet = gcnew Worksheet(gcnew SheetData()); // Add Sheets to the Workbook. Sheets^ sheets = spreadsheetDocument->WorkbookPart->Workbook->AppendChild<Sheets^>(gcnew Sheets()); // Append a new worksheet and associate it with the workbook. Sheet^ sheet = gcnew Sheet(); sheet->Id = spreadsheetDocument->WorkbookPart->GetIdOfPart(worksheetPart); sheet->SheetId = 1; sheet->Name = L"mySheet"; sheets->Append(sheet); workbookpart->Workbook->Save(); // Close the document. spreadsheetDocument->Close(); }
The code compiles, but the file created is not complete. Excel 2007 complains about a corrupt file. Upon examining the contents of the xlsx file it looks like the details of the "mySheet"-sheet class does not get written to disk. What am I missing in the C++/CLI code that this is not working correctly?
I am using Visual Studio 2013 targeting .Net Framework 4.0.
Read a very large Excel file using SAX parser
Hi All,
I have a very large Excel file (Column A - By) anf around 1 Lac rows.
My objective is to read this is Asp.net in a fastest way without impacting the performance.
For that, I created a sample console app and used SAX based approach and I was able to read pretty fast.
Problem is that, when I added the code in my asp.net, it is taking ages to even read the values.
I would be interested to know: in the fastest way to read an Excel file and convert the data into XML format from an asp.net app. Any readymade sample would really help.
Here is my code: (Please note that the following code works from console app great but performance really degrades when moved to asp.net app)
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
DocumentFormat.OpenXml;
using
DocumentFormat.OpenXml.Packaging;
using
OO=DocumentFormat.OpenXml.Spreadsheet;
using
System.Diagnostics;
namespace
WebApplication1
{
publicpartialclass_Default:Page
{
protectedvoidPage_Load(objectsender,EventArgse)
{
Stopwatchwatch =newStopwatch();
watch.Start();
StringfileName =@"C:\Users\ankushb\Desktop\TestData_Eligibility_File.xlsx";
// Comment one of the fo llowing lines to test the method separately.
//ReadExcelFileDOM(fileName); // DOM
ReadExcelFileSAX1(fileName);
// SAX
watch.Stop();
}
publicvoidReadExcelFileSAX1(stringfileName)
{
List<string> listShared = newList<string>();
using(SpreadsheetDocumentxl = SpreadsheetDocument.Open(fileName,false))
{
OO.
SharedStringItemssi;
using(OpenXmlReaderoxrShared = OpenXmlReader.Create(xl.WorkbookPart.SharedStringTablePart))
{
while(oxrShared.Read())
{
if(oxrShared.ElementType ==typeof(OO.SharedStringItem))
{
ssi = (OO.
SharedStringItem)oxrShared.LoadCurrentElement();
// this assumes the shared string is a simple text format, instead of rich text.
listShared.Add(ssi.Text.Text);
}
}
}
WorksheetPartwsp = xl.WorkbookPart.WorksheetParts.First();
OO.
Cellc;
using(OpenXmlReaderoxrCells = OpenXmlReader.Create(wsp))
{
while(oxrCells.Read())
{
if(oxrCells.ElementType ==typeof(OO.Cell))
{
c = (OO.
Cell)oxrCells.LoadCurrentElement();
// c = (OO.Cell)oxrCells.LoadCurrentElement();
// c.CellReference holds a string such as "A1"
if(c.DataType !=null)
{
if(c.DataType == OO.CellValues.SharedString)
{
// use whichever from-string-to-number conversion
// you like.
Console.Write(listShared[Convert.ToInt32(c.CellValue.Text)]);
//listShared[Convert.ToInt32(c.CellValue.Text)];
}
elseif(c.DataType == OO.CellValues.Number)
{
// "normal" value
//c.CellValue.Text;
}
// there's also boolean, which you might be interested
// as well as other types
}
else
{
// is by default a Number. Use this:
//c.CellValue.Text;
}
}
}
}
}
}
}
}
Preserving header and footer in merged Word document
I am trying to merge multiple DOCX files into one document using Open XML SDK 2. Using the code below (simplified to merge one file), I see the body of the source document in the target document, but I do not get the header and footer to merge. Can someone please help? Thank you.
Using myDoc As WordprocessingDocument = WordprocessingDocument.Open("c:\temp\starter.docx", True) Dim altChunkId As String = "AltChunkId1" Dim mainPart As MainDocumentPart = myDoc.MainDocumentPart Dim chunk As AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId) Using fileStream As FileStream = File.Open("c:\temp\letter.docx", FileMode.Open) chunk.FeedData(fileStream) End Using Dim altChunk As New AltChunk() altChunk.Id = altChunkId altChunk.AltChunkProperties = New AltChunkProperties() altChunk.AltChunkProperties.MatchSource = New MatchSource() altChunk.AltChunkProperties.MatchSource.Val = OnOffValue.FromBoolean(True) mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements(Of Paragraph)().Last()) mainPart.Document.Save() End Using
Customized ribbon group is shown twice -- customui.xml is in addition to the template file also saved in the docx file
The most weird thing is that it seems to depend on the user installation whether the customui.xml file is automatically included in the docx file. I tried it on several systems (all having 2007 installed): On some, the saved docx file includes the customui.xml file, on others it doesn't. I already checked all Word Options, but didn't find any relevant differences.
It would be great to find out how it can be prevented that Word copies the customui.xml file from the template into the docx file!
Thank you for your help!
Katja
C++/CLI Spreadsheet::Text How do I set the "Text" string? Getting C2273/C2228 errors.
DocumentFormat::OpenXml::Spreadsheet::Text class?
Using OpenXml SDK 2.5
Thanks!
// // Set the "C++->General->Resolve #using References" to the // appropriate directories. // #using <System.dll> #using <System.Core.dll> #using <WindowsBase.dll> // System::IO::Packaging #using <DocumentFormat.OpenXml.dll> using namespace System; using namespace DocumentFormat::OpenXml::Packaging; // need for WorkbookPart, SpreadsheetDocument, etc. using namespace DocumentFormat::OpenXml::Spreadsheet; // need for Workbook, Sheets, Sheet, etc. using namespace DocumentFormat::OpenXml; // need for SpreadsheetDocumentType::Workbook, etc. int main(array<System::String ^> ^args) { DocumentFormat::OpenXml::Spreadsheet::Text^ myText = gcnew DocumentFormat::OpenXml::Spreadsheet::Text(); // myText.Text = "hello"; // error C2228: left of '.Text' must have class/struct/union // myText->Text = "hello"; // error C2273: 'function-style cast' : illegal as right side of '->' operator return 0; }
Using Open XML SDK Code Snippets
I am having trouble using the reflect code for the whole excel document I created as a report sheet. I get a stack overflow error when trying to create that report sheet programmatically using the create package code.
private void button1_Click(object sender, EventArgs e)
{
//This is a main method used to call the generate class that generates excel documents
GeneratedClass gc = new GeneratedClass();
gc.CreatePackage("MAR.xlsx");
Really all I need to do though is have the computer copy and paste the one table I get when I export to excel from Lightswitch into the template report file. Right now I am using =cell (contents) references either within the same file or to another file to automatically transfer the data. The problem with that though is that the exported excel file has to have the user know to save the file with the correct name to the correct place so the lines of the table are copied to a sheet on the report sheet so I can use the data in the way it is formatted and displayed on in the report sheet file in excel.
I have been looking at code and found one of the snippets called XLGetCellForWriting formt the 2008 Open XML SDK that may help. I want to use it to write to the cells of the report sheet creating a table on a separate worksheet without having to write the whole file over again every time. Then just have one instance of the template file in a generic file directory like C:/Folder for Program/Excel file. I can then after the code snippet write a process start statement for that file location
//This opens the excel file from the current directory
Process.Start("MAR.xlsx");
Below is the code snippet but I am unsure how to use it there seems to be some XML code and some C# code here but I don’t know what I will need to add to my button handler to write to a specific cell and how to specify it use the table of data in my database to write to those cells. I am assuming I will have to write this snippet once for every cell and I know that I will only need so many rows of the database because after a certain number of rows it is unlikely that there will be more items in this case medications per patient would not exceed a number very high. Can you help me with an example of how to use this code to write to a cell one item from a database like the tables generated in Lightswitch?
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
<Title>Excel: Get cell for writing</Title>
<Author>Ken Getz</Author>
<Description>Given a spreadsheet document, a sheet name and an address, return a reference to a cell ready to accept a value. Create the cell if necessary.</Description>
<HelpUrl>
</HelpUrl>
<Shortcut>XLGetCellForWriting</Shortcut>
</Header>
<Snippet>
<References>
<Reference>
<Assembly>DocumentFormat.OpenXml</Assembly>
</Reference>
</References>
<Imports>
<Import>
<Namespace>System</Namespace>
</Import>
<Import>
<Namespace>System.Linq</Namespace>
</Import>
<Import>
<Namespace>DocumentFormat.OpenXml.Spreadsheet</Namespace>
</Import>
<Import>
<Namespace>System.Text.RegularExpressions</Namespace>
</Import>
<Import>
<Namespace>DocumentFormat.OpenXml.Packaging</Namespace>
</Import>
</Imports>
<Code Language="csharp"><![CDATA[
//using System;
//using System.Linq;
//using DocumentFormat.OpenXml.Spreadsheet;
//using System.Text.RegularExpressions;
//using DocumentFormat.OpenXml.Packaging;
// Given a reference to an Excel SpreadsheetDocument, the name of a sheet,
// and a cell address, return a reference to the cell. Throw an ArgumentException
// if the sheet doesn't exist. If the cell doesn't exist, create it.
public Cell XLGetCellForWriting(SpreadsheetDocument document, string sheetName, string address)
{
WorkbookPart wbPart = document.WorkbookPart;
// Find the sheet with the supplied name, and then use that Sheet object
// to retrieve a reference to the appropriate worksheet.
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
throw new ArgumentException("sheetName");
}
// Retrieve a reference to the worksheet part, and then use its Worksheet property to get
// a reference to the cell whose address matches the address you've supplied:
WorksheetPart wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));
Worksheet ws = wsPart.Worksheet;
Cell theCell = ws.Descendants<Cell>().
Where(c => c.CellReference == address).FirstOrDefault();
// If the cell doesn't exist, create it:
if (theCell == null)
{
theCell = InsertCellInWorksheet(ws, address);
}
return theCell;
}
// Given a Worksheet and an address (like "AZ254"), either return a cell reference, or
// create the cell reference and return it.
private Cell InsertCellInWorksheet(Worksheet ws, string addressName)
{
// Use regular expressions to get the row number and column name.
// If the parameter wasn't well formed, this code
// will fail:
Regex rx = new Regex("^(?<col>\\D+)(?<row>\\d+)");
Match m = rx.Match(addressName);
uint rowNumber = uint.Parse(m.Result("${row}"));
string colName = m.Result("${col}");
SheetData sheetData = ws.GetFirstChild<SheetData>();
string cellReference = (colName + rowNumber.ToString());
Cell theCell = null;
// If the worksheet does not contain a row with the specified row index, insert one.
var theRow = sheetData.Elements<Row>().
Where(r => r.RowIndex.Value == rowNumber).FirstOrDefault();
if (theRow == null)
{
theRow = new Row();
theRow.RowIndex = rowNumber;
sheetData.Append(theRow);
}
// If the cell you need already exists, return it.
// If there is not a cell with the specified column name, insert one.
Cell refCell = theRow.Elements<Cell>().
Where(c => c.CellReference.Value == cellReference).FirstOrDefault();
if (refCell != null)
{
theCell = refCell;
}
else
{
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
foreach (Cell cell in theRow.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
theCell = new Cell();
theCell.CellReference = cellReference;
theRow.InsertBefore(theCell, refCell);
}
return theCell;
}
]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
OpenXml,Excel,C#
Hi,
Please explain, how to freeze particular row in the excel sheet using openXML in C#.
thanks,
Elangovan P