OpenXML sdk Modify a sheet in my Excel document - openxml

I create an empty template in excel.
I would like to open the template and edit the document but I do not know how to change the existing sheet.
That's the code:
using (SpreadsheetDocument xl = SpreadsheetDocument.Open(filename, true))
{
WorkbookPart wbp = xl.WorkbookPart;
WorkbookPart workbook = xl.WorkbookPart;
// Get the worksheet with the required name.
// To be used to match the ID for the required sheet data
// because the Sheet class and the SheetData class aren't
// linked to each other directly.
Sheet s = null;
if (wbp.Workbook.Sheets.Elements().Count(nm => nm.Name == sheetName) == 0)
{
// no such sheet with that name
xl.Close();
return;
}
else
{
s = (Sheet)wbp.Workbook.Sheets.Elements().Where(nm => nm.Name == sheetName).First();
}
WorksheetPart wsp = (WorksheetPart)xl.WorkbookPart.GetPartById(s.Id.Value);
Worksheet worksheet = new Worksheet();
SheetData sd = new SheetData();
//SheetData sd = (SheetData)wsp.Worksheet.GetFirstChild();
Stylesheet styleSheet = workbook.WorkbookStylesPart.Stylesheet;
//SheetData sheetData = new SheetData();
//build the formatted header style
UInt32Value headerFontIndex =
util.CreateFont(
styleSheet,
"Arial",
10,
true,
System.Drawing.Color.Red);
//build the formatted date style
UInt32Value dateFontIndex =
util.CreateFont(
styleSheet,
"Arial",
8,
true,
System.Drawing.Color.Black);
//set the background color style
UInt32Value headerFillIndex =
util.CreateFill(
styleSheet,
System.Drawing.Color.Black);
//create the cell style by combining font/background
UInt32Value headerStyleIndex =
util.CreateCellFormat(
styleSheet,
headerFontIndex,
headerFillIndex,
null);
/*
* Create a set of basic cell styles for specific formats...
* If you are controlling your table then you can simply create the styles you need,
* this set of code is still intended to be generic.
*/
_numberStyleId = util.CreateCellFormat(styleSheet, null, null, UInt32Value.FromUInt32(3));
_doubleStyleId = util.CreateCellFormat(styleSheet, null, null, UInt32Value.FromUInt32(4));
_dateStyleId = util.CreateCellFormat(styleSheet, null, null, UInt32Value.FromUInt32(14));
_textStyleId = util.CreateCellFormat(styleSheet, headerFontIndex, headerFillIndex, null);
_percentageStyleId = util.CreateCellFormat(styleSheet, null, null, UInt32Value.FromUInt32(9));
util.AddNumber(xl, sheetName, (UInt32)3, "E", "27", _numberStyleId);
util.AddNumber(xl, sheetName, (UInt32)3, "F", "3.6", _doubleStyleId);
util.AddNumber(xl, sheetName, (UInt32)5, "L", "5", _percentageStyleId);
util.AddText(xl, sheetName, (UInt32)5, "M", "Dario", _textStyleId);
util.AddDate(xl, sheetName, (UInt32)3, "J", DateTime.Now, _dateStyleId);
util.AddImage(xl, sheetName, imagePath, "Smile", "Smile", 30, 30);
util.MergeCells(xl, sheetName, "D12", "F12");
//util.DeleteValueCell(spreadsheet, sheetName, "F", (UInt32)8);
txtCellText.Text = util.GetCellValue(xl, sheetName, (UInt32)5, "M");
double number = util.GetCellDoubleValue(xl, sheetName, (UInt32)3, "E");
double numberD = util.GetCellDoubleValue(xl, sheetName, (UInt32)3, "F");
DateTime datee = util.GetCellDateTimeValue(xl, sheetName, (UInt32)3, "J");
//txtDoubleCell.Text = util.GetCellValue(spreadsheet, sheetName, (UInt32)3, "P");
txtPercentualeCell.Text = util.GetCellValue(xl, sheetName, (UInt32)5, "L");
string date = util.GetCellValue(xl, sheetName, (UInt32)3, "J");
double dateD = Convert.ToDouble(date);
DateTime dateTime = DateTime.FromOADate(dateD);
txtDateCell.Text = dateTime.ToShortDateString();
//worksheet.Append(sd);
/*
Columns columns = new Columns();
columns.Append(util.CreateColumnData(10, 10, 40));
worksheet.Append(columns);
*/
SheetProtection sheetProtection1 = new SheetProtection() { Sheet = true, Objects = true, Scenarios = true, SelectLockedCells = true, SelectUnlockedCells = true };
worksheet.Append(sheetProtection1);
wsp.Worksheet = worksheet;
wsp.Worksheet.Save();
xl.WorkbookPart.Workbook.Save();
xl.Close();
thanks!
Update
I try it but it doesn't work.I'm using yet this method (GetWorksheetPart() ) but i want to get the existing worksheet, edit it and save the new document modified.
using (SpreadsheetDocument xl = SpreadsheetDocument.Open(filename, true))
{
WorkbookPart wbp = xl.WorkbookPart;
WorksheetPart worksheetPart = util.GetWorksheetPart(wbp, sheetName);
SheetProtection sheetProtection1 = new SheetProtection() { Sheet = true, Objects = true, Scenarios = true, SelectLockedCells = true, SelectUnlockedCells = true };
worksheetPart.Worksheet.Append(sheetProtection1);
worksheetPart.Worksheet.Save(); </pre></code>
I build the document BUT is corrupt. why?

To get an existing worksheet to edit use this code to get the part:
public static WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
{
string relId = workbookPart.Workbook.Descendants<Sheet>()
.Where(s => sheetName.Equals(s.Name))
.First()
.Id;
return (WorksheetPart)workbookPart.GetPartById(relId);
}
Just make sure that the sheetname exists you are searching for or you will get some exceptions. Then use the reference to that worksheetpart to perform any edits your want and at the end just call worksheetPart.Worksheet.Save();
EDIT
The SheetProtection element needs to be inserted after the SheetData element. Try this line when appending: worksheetPart.Worksheet.Descendants<SheetData>().First().InsertAfterSelf(sheetProtection1);

Related

Table cell margin with Open XML

I would like to define cell margin at table level, just like here: OOXML
with the following code:
var mainDocumentPart = wordDocument.AddMainDocumentPart();
mainDocumentPart.Document = new Document(
new Body(
new Paragraph(
new Run(
new Text("Create text in body - CreateWordprocessingDocument")))));
// Create an empty table.
Table table = new Table();
// Create a TableProperties object and specify its border information.
TableProperties tblProp = new TableProperties(
new TableCellSpacing() { Width = "200", Type = TableWidthUnitValues.Dxa },
new TableCellMargin(
new TopMargin() { Width = "50", Type = TableWidthUnitValues.Dxa },
new StartMargin() { Width = "200", Type = TableWidthUnitValues.Dxa },
new BottomMargin() { Width = "0", Type = TableWidthUnitValues.Dxa },
new EndMargin() { Width = "0", Type = TableWidthUnitValues.Dxa })
);
The cell spacing works, but the cell margin not. What do I wrong?
Use TableCellMarginDefault in place of TableCellMargin.
TableCellMarginDefault affects the table.
TableCellMargin affects a single cell.
Your new code should look like this:
var mainDocumentPart = wordDocument.AddMainDocumentPart();
mainDocumentPart.Document = new Document(
new Body(
new Paragraph(
new Run(
new Text("Create text in body - CreateWordprocessingDocument")))));
// Create an empty table.
Table table = new Table();
// Create a TableProperties object and specify its border information.
TableProperties tblProp = new TableProperties(
new TableCellSpacing() { Width = "200", Type = TableWidthUnitValues.Dxa },
new TableCellMarginDefault(
new TopMargin() { Width = "50", Type = TableWidthUnitValues.Dxa },
new StartMargin() { Width = "200", Type = TableWidthUnitValues.Dxa },
new BottomMargin() { Width = "0", Type = TableWidthUnitValues.Dxa },
new EndMargin() { Width = "0", Type = TableWidthUnitValues.Dxa })
);

How columns should be manged in OpenXML

I have ceated a excel file with OpenXMl library with the follwing code.
The columns do not get theit widths as they are defined in the code.
Has anybody an idea?
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet.Save();
// Make the columns in the worksheet
var columns = worksheetPart.Worksheet.GetFirstChild<Columns>();
bool needToInsertColumns = false;
if (columns == null)
{
columns = new Columns();
needToInsertColumns = true;
}
Column column1 = new Column() { CustomWidth = true, Width = 5};
columns.Append(column1);
// Insert the columns into the Worksheet
if (needToInsertColumns)
worksheetPart.Worksheet.InsertAt(columns, 0);
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Employees" };
sheets.Append(sheet);
workbookPart.Workbook.Save();
worksheetPart.Worksheet.Save();
document.Save();
I have tried the following and have success:
var columns = new Columns();
var column1 = new Column { Min = 1, Max = 1, Width = 5, CustomWidth = true };
var column2 = new Column { Min = 2, Max = 2, Width = 10, CustomWidth = true };
var column3 = new Column { Min = 3, Max = 3, Width = 5, CustomWidth = true };
var column4 = new Column { Min = 4, Max = 4, Width = 20, CustomWidth = true };
var column5 = new Column { Min = 5, Max = 5, Width = 50, CustomWidth = true };
columns.Append(column1);
columns.Append(column2);
columns.Append(column3);
columns.Append(column4);
columns.Append(column5);
worksheetPart.Worksheet.Append(columns);

When using NumericField, get absolutely nothing back every time

Been playing with Lucene.NET the last two days.
After reading up on Dates, I was led to believe that Dates are best converted to Milliseconds, and stored in NumericField, with Indexing=true, and Store=No.
But now nothing ever returns - it must be something basic, but I'm just not seeing it.
The saving code is as follows:
...
else if (type == typeof (DateTime?))
{
var typedValue = (DateTime?) value;
field = numericField = new NumericField(documentFieldName, 4, Field.Store.YES, true);
long milliseconds = typedValue.HasValue?(typedValue.Value.Date.Ticks/TimeSpan.TicksPerMillisecond):0;
numericField.SetLongValue(milliseconds);
doc.Add(numericField);
}
...
else
{
field = stringField = new Field(
documentFieldName,
(value != null)?value.ToString():string.Empty,
Store.YES,
Field.Index.ANALYZED) ;
doc.Add(stringField);
}
// Write the Document to the catalog
indexWriter.AddDocument(doc);
When I query for docs against the values saved in Field ... no problem.
When I query for documents by matching against the values in NumericFields, nothing returns.
Where did I go wrong?
Thanks for your help.
Lucene.Net.Analysis.Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
var q2 = NumericRangeQuery.NewLongRange("Val", 3, 3, true, true);
var uxy2 = documentSearchManagementService.Search("Students", termQuery, "Id");
Using:
public ScoredDocumentResult[] Search(string indexName, Query query, params string[] hitFieldNamesToReturn)
{
if (_configuration.IndexRootDirectory.IsNullOrEmpty())
{
throw new Exception("Configuration.IndexRootDirectory has not been configued yet.");
}
indexName.ValidateIsNotNullOrEmpty("indexName");
hitFieldNamesToReturn.ValidateIsNotDefault("hitFieldNamesToReturn");
//Specify the index file location where the indexes are to be stored
string indexFileLocation = Path.Combine(_configuration.IndexRootDirectory, indexName);
Lucene.Net.Store.Directory luceneDirectory = Lucene.Net.Store.FSDirectory.Open(indexFileLocation);
IndexSearcher indexSearcher = new IndexSearcher(luceneDirectory);
TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.Create(10, true);
indexSearcher.Search(query, topScoreDocCollector);
List<ScoredDocumentResult> results = new List<ScoredDocumentResult>();
foreach (var scoreDoc in topScoreDocCollector.TopDocs(0, 10).ScoreDocs)
{
ScoredDocumentResult resultItem = new ScoredDocumentResult();
Lucene.Net.Documents.Document doc = indexSearcher.Doc(scoreDoc.Doc);
resultItem.Score = scoreDoc.Score;
List<ScoredDocumentFieldResult> fields = new List<ScoredDocumentFieldResult>();
foreach (string fieldName in hitFieldNamesToReturn)
{
string fieldValue = doc.Get(fieldName);
fields.Add(new ScoredDocumentFieldResult{Key= fieldName,Value=fieldValue});
}
resultItem.FieldValues = fields.ToArray();
results.Add(resultItem);
}
indexSearcher.Close();
return results.ToArray();
}

How to make a column with a string and pixbuf in GtkTreeview?

I'm working in a app with Gtk+2 and i need to implement a File treeview.
the actual code it's:
public FileTree() {
store = new TreeStore(2,typeof(string),typeof(string));
this.change_dir( "/dir/path" );
set_model( store );
// File icon
var pixbuf = new Gtk.CellRendererPixbuf();
var column = new Gtk.TreeViewColumn();
column.set_title("");
column.pack_start(pixbuf, false);
column.add_attribute(pixbuf,"stock-id",0);
column.set_alignment(1.0f);
append_column (column);
// File name
Gtk.CellRenderer cell = new Gtk.CellRendererText();
insert_column_with_attributes(-1,"", cell, "text", 1);
// Do some visual configs
this.config();
}
and change_dir():
public void change_dir( string path ) {
File repo_dir = File.new_for_path( path );
try {
generate_list( repo_dir, null, new Cancellable());
} catch ( Error e ) {
stderr.printf("Error: %s\n", e.message);
}
}
public void generate_list (
File file,
TreeIter? parent = null,
Cancellable? cancellable = null
) throws Error {
// Enumerator
FileEnumerator enumerator = file.enumerate_children (
"standard::*",
FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable
);
FileInfo info = null;
TreeIter iter;
while(cancellable.is_cancelled() == false && ((info = enumerator.next_file(cancellable)) != null ))
{
// Check if not it's in the omited files.
if( ! (info.get_name() in IGNORED ) ) {
// Check if is a dir or a file
if( info.get_file_type() == FileType.DIRECTORY ) {
this.store.append( out iter, parent);
this.store.set(iter, 0, STOCK_DIRECTORY, 1, info.get_name());
File subdir = file.resolve_relative_path(info.get_name());
this.generate_list(subdir, iter, cancellable );
} else {
// It's a file
this.store.append( out iter, parent);
this.store.set(iter, 0, STOCK_FILE, 1, info.get_name());
}
}
}
if ( cancellable.is_cancelled()) {
throw new IOError.CANCELLED ("Operation was cancelled");
}
}
This it's showing two columns in ( first with a folder/file icon and the second one the name of the folder/file)
it's some way to do this in one single column??
EDIT: it could be some hack to set the icon at the side of the name, the actual code shows the icon and the string but when i expand a column, the strings moves a little to the right and there's a blank space between the icon and string.
With the method of the TreeViewColumn, pack_start(), I Just append any cell renderer to the column.
(in C this is like http://developer.gnome.org/gtk/unstable/gtk-question-index.html (see 5.3))
so, just modified:
// File icon
var pixbuf = new Gtk.CellRendererPixbuf();
var column = new Gtk.TreeViewColumn();
column.set_title("");
column.pack_start(pixbuf, false);
column.add_attribute(pixbuf,"stock-id",0);
column.set_alignment(1.0f);
append_column (column);
// File name
Gtk.CellRenderer cell = new Gtk.CellRendererText();
insert_column_with_attributes(-1,"", cell, "text", 1);
with:
// File icon
var pixbuf = new Gtk.CellRendererPixbuf();
column.set_title("");
column.pack_start(pixbuf, false);
column.add_attribute(pixbuf,"stock-id",0);
// The name of the file.
var cell = new Gtk.CellRendererText();
column.pack_start(cell, false);
column.add_attribute(cell,"text",1);
append_column (column);
And there it is :)

Can not add bullets for word using OpenXml

My expected result is:
Hello
world!
but when i using below codes:
MainDocumentPart mainDocumentPart =
package.AddMainDocumentPart();
DocumentFormat.OpenXml.Wordprocessing.Document elementW =
new DocumentFormat.OpenXml.Wordprocessing.Document(
new Body(
new DocumentFormat.OpenXml.Wordprocessing.Paragraph(
new NumberingProperties(
new NumberingLevelReference() { Val = 0 },
new NumberingId() { Val = 1 })
),
new Run(
new RunProperties(),
new Text("Hello, ") { Space = new DocumentFormat.OpenXml.EnumValue<DocumentFormat.OpenXml.SpaceProcessingModeValues> { InnerText = "preserve" } })),
new DocumentFormat.OpenXml.Wordprocessing.Paragraph(
new ParagraphProperties(
new NumberingProperties(
new NumberingLevelReference() { Val = 0 },
new NumberingId() { Val = 1 })),
new Run(
new RunProperties(),
new Text("world!")
{
Space = new DocumentFormat.OpenXml.EnumValue<DocumentFormat.OpenXml.SpaceProcessingModeValues> { InnerText = "preserve" }
})));
elementW.Save(mainDocumentPart);
Result is:
Hello
world!
How can i get my expected result?
I realize this is far too late but maybe it can help others with the same question. The marked answer (by amurra) doesn't actually achieve the desired result. It simply creates a document with the list as content, just more completely than you. What you have added to the main document part is fine.
In the XML format, list items are defined as paragraphs with an indentation level and a numbering ID. This ID references the numbering rules defined in the NumberingDefinitionsPart of the document.
In your case, because you've set the numbering ID to be 1, the following code would map that ID of 1 to reflect a bulleted list as desired. Note the NumberingFormat and LevelText objects inside the Level object. These are the key components for your formatting.
NumberingDefinitionsPart numberingPart =
mainDocumentPart.AddNewPart<NumberingDefinitionsPart>("myCustomNumbering");
Numbering numElement = new Numbering(
new AbstractNum(
new Level(
new NumberingFormat() { Val = NumberFormatValues.Bullet },
new LevelText() { Val = "ยท" }
) { LevelIndex = 0 }
) { AbstractNumberId = 0 },
new NumberingInstance(
new AbstractNumId(){ Val = 0 }
){ NumberID = 1 }
);
numElement.Save(numberingPart);
For more information, check out the documentation for all the related classes on the Wordprocessing Namespace on MSDN, or the Working With Numbering markup article.
This should create you a blank document with your expected output:
// Creates an Document instance and adds its children.
public Document GenerateDocument()
{
Document document1 = new Document();
document1.AddNamespaceDeclaration("ve", "http://schemas.openxmlformats.org/markup-compatibility/2006");
document1.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
document1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
document1.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
document1.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
document1.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
document1.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
document1.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
document1.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
Body body1 = new Body();
Paragraph paragraph1 = new Paragraph(){ RsidParagraphAddition = "00AF4948", RsidParagraphProperties = "00625634", RsidRunAdditionDefault = "00625634" };
ParagraphProperties paragraphProperties1 = new ParagraphProperties();
ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId(){ Val = "ListParagraph" };
NumberingProperties numberingProperties1 = new NumberingProperties();
NumberingLevelReference numberingLevelReference1 = new NumberingLevelReference(){ Val = 0 };
NumberingId numberingId1 = new NumberingId(){ Val = 1 };
numberingProperties1.Append(numberingLevelReference1);
numberingProperties1.Append(numberingId1);
paragraphProperties1.Append(paragraphStyleId1);
paragraphProperties1.Append(numberingProperties1);
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Hello";
run1.Append(text1);
paragraph1.Append(paragraphProperties1);
paragraph1.Append(run1);
Paragraph paragraph2 = new Paragraph(){ RsidParagraphAddition = "00625634", RsidParagraphProperties = "00625634", RsidRunAdditionDefault = "00625634" };
ParagraphProperties paragraphProperties2 = new ParagraphProperties();
ParagraphStyleId paragraphStyleId2 = new ParagraphStyleId(){ Val = "ListParagraph" };
NumberingProperties numberingProperties2 = new NumberingProperties();
NumberingLevelReference numberingLevelReference2 = new NumberingLevelReference(){ Val = 0 };
NumberingId numberingId2 = new NumberingId(){ Val = 1 };
numberingProperties2.Append(numberingLevelReference2);
numberingProperties2.Append(numberingId2);
paragraphProperties2.Append(paragraphStyleId2);
paragraphProperties2.Append(numberingProperties2);
Run run2 = new Run();
Text text2 = new Text();
text2.Text = "world!";
run2.Append(text2);
paragraph2.Append(paragraphProperties2);
paragraph2.Append(run2);
SectionProperties sectionProperties1 = new SectionProperties(){ RsidR = "00625634", RsidSect = "00AF4948" };
HeaderReference headerReference1 = new HeaderReference(){ Type = HeaderFooterValues.Even, Id = "rId7" };
HeaderReference headerReference2 = new HeaderReference(){ Type = HeaderFooterValues.Default, Id = "rId8" };
FooterReference footerReference1 = new FooterReference(){ Type = HeaderFooterValues.Even, Id = "rId9" };
FooterReference footerReference2 = new FooterReference(){ Type = HeaderFooterValues.Default, Id = "rId10" };
HeaderReference headerReference3 = new HeaderReference(){ Type = HeaderFooterValues.First, Id = "rId11" };
FooterReference footerReference3 = new FooterReference(){ Type = HeaderFooterValues.First, Id = "rId12" };
PageSize pageSize1 = new PageSize(){ Width = (UInt32Value)12240U, Height = (UInt32Value)15840U };
PageMargin pageMargin1 = new PageMargin(){ Top = 1440, Right = (UInt32Value)1440U, Bottom = 1440, Left = (UInt32Value)1440U, Header = (UInt32Value)720U, Footer = (UInt32Value)720U, Gutter = (UInt32Value)0U };
Columns columns1 = new Columns(){ Space = "720" };
DocGrid docGrid1 = new DocGrid(){ LinePitch = 360 };
sectionProperties1.Append(headerReference1);
sectionProperties1.Append(headerReference2);
sectionProperties1.Append(footerReference1);
sectionProperties1.Append(footerReference2);
sectionProperties1.Append(headerReference3);
sectionProperties1.Append(footerReference3);
sectionProperties1.Append(pageSize1);
sectionProperties1.Append(pageMargin1);
sectionProperties1.Append(columns1);
sectionProperties1.Append(docGrid1);
body1.Append(paragraph1);
body1.Append(paragraph2);
body1.Append(sectionProperties1);
document1.Append(body1);
return document1;
}