Im using OpenXML SDK 2.5 for creating excel file. I want to hide gridlines on created excel files.I was tried creating SheetViews but it completely hide sheet. My pure code as below
public static SpreadsheetDocument CreateWorkbook(MemoryStream memoryStream)
{
var spreadSheet = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook);
spreadSheet.AddWorkbookPart();
spreadSheet.WorkbookPart.Workbook = new Workbook();
spreadSheet.WorkbookPart.Workbook.Save();
var sharedStringTablePart = spreadSheet.WorkbookPart.AddNewPart<SharedStringTablePart>();
sharedStringTablePart.SharedStringTable = new SharedStringTable();
sharedStringTablePart.SharedStringTable.Save();
spreadSheet.WorkbookPart.Workbook.Sheets = new Sheets();
spreadSheet.WorkbookPart.Workbook.Save();
var workbookStylesPart = spreadSheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet.Save();
memoryStream.Seek(0, SeekOrigin.Begin);
return spreadSheet;
}
public static bool AddWorksheet(SpreadsheetDocument spreadsheet, string name)
{
Sheets sheets = spreadsheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
var worksheetPart = spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
worksheetPart.Worksheet.Save();
var sheet = new Sheet()
{
Id = spreadsheet.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = (uint)(spreadsheet.WorkbookPart.Workbook.Sheets.Count() + 1),
Name = name
};
if (string.IsNullOrEmpty(name)) {
sheet.Name = string.Format("Sheet{0}", sheet.SheetId);
}
sheets.Append(sheet);
spreadsheet.WorkbookPart.Workbook.Save();
return true;
}
After that im creating instance of spreadsheet in memory
//Creating like that
var memoryStream = new MemoryStream();
var spreadsheet = CreateWorkbook(memoryStream);
AddWorksheet(spreadsheet, null);
//End Filling data
After some check i decide to, when you use the column you couldnt hide gridlines. You should only cell for showing data. But that time you couldnt change width property bacause column doesnt extist :)
Okay. First be sure your pure works properly and generates valid workbook. After that you can apply code:
SheetViews sheetViews = new SheetViews();
SheetView sheetView = new SheetView(){ ShowGridLines = false, TabSelected = true, ZoomScaleNormal = (UInt32Value)100U, WorkbookViewId = (UInt32Value)0U };
Selection selection = new Selection(){ ActiveCell = "A1", SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A1" } };
sheetView.Append(selection);
sheetViews.Append(sheetView);
worksheet.Append(sheetViews);
Be sure that your sheetViews block is placed before sheetdata, or you will have corrupt document.
Related
I tried to create an excel with multiple sheets and different data count in both sheets. but when i tried to create only one row was getting added in both sheets and not more than that and when i open the excel it asks for repair.
`
MemoryStream ms = new MemoryStream();
SpreadsheetDocument xl = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
byte[] dt = null;
// Add a WorkbookPart to the document
WorkbookPart workbookPart = xl.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
tracing.Trace("Temp Plugin Executed");
Sheets sheets = xl.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Begin: Code block for Excel sheet 1
WorksheetPart worksheetPart1 = workbookPart.AddNewPart<WorksheetPart>();
Worksheet workSheet1 = new Worksheet();
SheetData sheetData1 = new SheetData();
// the data for sheet 1
Row rowInSheet1 = new Row();
Cell emptyCell = CreateTextCell("A", "111", 1);
rowInSheet1.Append(emptyCell);
sheetData1.Append(rowInSheet1);
workSheet1.Append(sheetData1);
worksheetPart1.Worksheet = workSheet1;
Sheet sheet1 = new Sheet()
{
Id = xl.WorkbookPart.GetIdOfPart(worksheetPart1),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet1);
// End: Code block for Excel sheet 1
// Begin: Code block for Excel sheet 2
WorksheetPart worksheetPart2 = workbookPart.AddNewPart<WorksheetPart>();
Worksheet workSheet2 = new Worksheet();
SheetData sheetData2 = new SheetData();
// the data for sheet 2
Row rowInSheet2 = new Row();
Cell mycell = CreateTextCell("A", "data", 1);
Cell mycell1 = CreateTextCell("A", "data", 2);
rowInSheet2.Append(mycell);
rowInSheet2.Append(mycell1);
sheetData2.Append(rowInSheet2);
workSheet2.Append(sheetData2);
worksheetPart2.Worksheet = workSheet2;
Sheet sheet2 = new Sheet()
{
Id = xl.WorkbookPart.GetIdOfPart(worksheetPart2),
SheetId = 2,
Name = "Sheet2"
};
sheets.Append(sheet2);
xl.Close();
dt = ms.ToArray();
public Cell CreateTextCell(string header, string text, int index)
{
//Create a new inline string cell.
Cell c = new Cell();
c.DataType = CellValues.InlineString;
c.CellReference = header + index;
//Add text to the text cell.
InlineString inlineString = new InlineString();
Text t = new Text();
t.Text = text;
inlineString.AppendChild(t);
c.AppendChild(inlineString);
return c;
}
`
I tried creating multiple sheets with different data count on both sheets
The second cell should be B1 not A2. It's the second cell in the first row. That's how Excel works. So the code should look like:
Cell mycell = CreateTextCell("A", "data", 1);
Cell mycell1 = CreateTextCell("B", "data2", 1);
To add a second row on the second worksheet:
// the data for sheet 2
Row row2InSheet2 = new Row() { RowIndex = 2 };
sheetData2.Append(row2InSheet2);
// In the new row, find the column location to insert a cell in A2.
Cell refCell = null;
foreach (Cell cell in row2InSheet2.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, "A2", true) > 0)
{
refCell = cell;
break;
}
}
Cell mycellRow21 = CreateTextCell("A", "new_row_test1", 2);
row2InSheet2.InsertBefore(mycellRow21, refCell);
You can study the Microsoft documentation on OpenXml for more examples
Use DocumentFormat.Openxml 2.8.1.
I try to create Excel Sheet and create Table inside it.
But when i do it - and try to open excel file - excel says that can not open and try to restore this file.
So, i create excel file:
var fStream = new FileStream(tempPathName, FileMode.Open, FileAccess.ReadWrite, FileShare.None, 1048, FileOptions.DeleteOnClose);
SpreadsheetDocument ssDoc = SpreadsheetDocument.Create(inputStream,
SpreadsheetDocumentType.Workbook);
Then , create sheet:
var tempPathName = Path.GetTempFileName();
WorkbookPart workbookPart = ssDoc.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
Sheets sheets = ssDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
WorksheetPart worksheetPart4 = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart4.Worksheet = new Worksheet();
Worksheet workSheet4 = worksheetPart4.Worksheet;
var table = CreateTable1();
TableParts tableParts = new TableParts() { Count = (UInt32)1 };
TablePart tablePart = new TablePart() { Id = "rId" + 1 };
tableParts.Append(table);
tableParts.Append(tablePart);
workSheet4.AppendChild(tableParts);
Sheet sheet4 = new Sheet()
{
Id = ssDoc.WorkbookPart.GetIdOfPart(worksheetPart4),
SheetId = 4,
Name = "test"
};
sheets.Append(sheet4);
ssDoc.Close();
private Table CreateTable1()
{
// First, we create the table, its properties and we append it.
Table table = new Table();
TableProperties props = new TableProperties();
table.AppendChild<TableProperties>(props);
// Now we create a new layout and make it "fixed".
TableLayout tl = new TableLayout() { Type = TableLayoutValues.Fixed };
props.TableLayout = tl;
// Then we just create a new row and a few cells and we give them a width
var tr = new TableRow();
var tc1 = new TableCell();
var tc2 = new TableCell();
tc1.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
tc2.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
table.Append(tr);
return table;
}
So, how to create table in Excel sheet and insert data in table?
Thank you.
TableStyle class is what you`re looking for.
You actually have to create TableStyle and add it to your spreadsheet.
In CreateTable1(), TableProperties, TableLayout, TableRow, and TableCell are WordProcessing elements.
Instead, you will want to use code similar to this:
private void CreateTable2(SheetData sheetData)
{
var row1 = new Row(){ RowIndex = 1 };
sheetData.Append(row1);
var cell1 = new Cell();
cell1.DataType = CellValues.InlineString;
cell1.InlineString = new InlineString() { Text = new Text("Hello") };
row1.InsertAt(cell1, 0);
var cell2 = new Cell();
cell2.DataType = CellValues.InlineString;
cell2.InlineString = new InlineString() { Text = new Text("World") };
row1.InsertAt(cell2, 1);
}
Slightly modify the rest of your code to look like the following (most of which I borrowed from here).
var fStream = new FileStream(tempPathName, FileMode.Create);
SpreadsheetDocument ssDoc = SpreadsheetDocument.Create(fStream, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
WorkbookPart workbookPart = ssDoc.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = ssDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = ssDoc.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheet"
};
sheets.Append(sheet);
// Get the sheetData cell table.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
CreateTable2(sheetData);
workbookPart.Workbook.Save();
ssDoc.Close();
fStream.Close();
I am trying to download the large excel file using open xml. I am able to download it. My excel file contains more than 100k records. When I double click on the file, I get below error message.
Below is my code.
public MemoryStream WriteExcelUsingOpenXML(IEnumerable<string> headers, IEnumerable<IEnumerable<string>> values, string worksheetName)
{
var stream = new MemoryStream();
var headersArray = headers.ToArray();
using (SpreadsheetDocument document = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = Constants.TimephaseWorksheet };
sheets.Append(sheet);
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
// Constructing header
Row row = new Row();
foreach (var data in headersArray)
{
row.Append(ConstructCell(headersArray[0], CellValues.SharedString));
}
// Insert the header row to the Sheet Data
sheetData.AppendChild(row);
// Inserting each employee
foreach (var valuesEnumeration in values)
{
row = new Row();
var flattend = valuesEnumeration.ToArray();
row.Append(
ConstructCell(flattend[0], CellValues.Number),
ConstructCell(flattend[1], CellValues.SharedString),
ConstructCell(flattend[2], CellValues.SharedString),
ConstructCell(flattend[3], CellValues.Number),
ConstructCell(flattend[4], CellValues.SharedString));
sheetData.AppendChild(row);
}
worksheetPart.Worksheet.Save();
}
return stream;
}
private Cell ConstructCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
};
}
Below is the sample data of excel file.
How to fix the error?
I have exported the report to Excel and it works fine, but when I print the file the width of the spreadsheet doesn't fit all column into one page. For this to happen I have to change the Page Layout, and set the scaling to fit 1 on width and 43 tall. How can I get this from code?
using (var workbook = SpreadsheetDocument.Create(Savepath, SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook();
workbook.WorkbookPart.Workbook.Sheets = new Sheets();
//declare our MergeCells here
MergeCells mergeCells = null;
foreach (DataRow dsrow in table.Rows)
{
int innerColIndex = 0;
rowIndex++;
Row newRow = new Row();
foreach (String col in columns)
{
Stylesheet stylesheet1 = new Stylesheet();
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dsrow[col].ToString());
cell.CellReference = excelColumnNames[innerColIndex] + rowIndex.ToString();
if (table.TableName == "Work Order Report")
{
string cellNameWorkOrder = dsrow[col].ToString();
if (cellNameWorkOrder == "POSTER: 10% MUST HAVE APPROACH AND CLOSE-UP SHOTS - PHOTO OF EACH CREATIVE" || cellNameWorkOrder == "BULLETINS: 100% CLOSE-UP AND APPROACH OF EACH UNIT")
{
if (mergeCells == null)
mergeCells = new MergeCells();
var cellAddress = cell.CellReference;
var cellAddressTwo = "I" + rowIndex.ToString();
mergeCells.Append(new MergeCell() { Reference = new StringValue(cellAddress + ":" + cellAddressTwo) });
}
}
newRow.AppendChild(cell);
innerColIndex++;
}
sheetData.AppendChild(newRow);
}
//add the mergeCells to the worksheet if we have any
if (mergeCells != null)
sheetPart.Worksheet.InsertAfter(mergeCells, sheetPart.Worksheet.Elements<SheetData>().First());
}
workbook.WorkbookPart.Workbook.Save();
}
The excel report looks like https://www.screencast.com/t/CCMR96Mw7u when I print now its like https://www.screencast.com/t/MkTpDc98RD0l ,https://www.screencast.com/t/MRyzpEiFICM the expected result is https://www.screencast.com/t/ztgvm6mISSwp
In order to achieve this you need to do two things. Firstly, you need to add a PageSetupProperties instance to a SheetProperties instance which in turn should get added to your Worksheet. The PageSetupProperties has a FitToPage property which is the part that sets the radio button in Excel to "Fit to".
Next, you need to use the PageSetup class in order to set the width and height required. This is done via the FitToWidth and FitToHeight properties. The PageSetup also needs to be added to the Worksheet.
Note that the order of the elements is important, you can see the correct order in the ECMA spec.
The following is a self contained example that adds one cell and then sets the properties the way that you need them:
using (SpreadsheetDocument myDoc = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookpart = myDoc.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
SheetData sheetData = new SheetData();
//add a row
Row row = new Row();
row.RowIndex = 1;
//create a cell
Cell cell = new Cell();
cell.CellReference = "A1";
CellValue cellValue = new CellValue();
cellValue.Text = "123";
cell.Append(cellValue);
row.AppendChild(cell);
sheetData.AppendChild(row);
// Add a WorkbookPart to the document.
worksheetPart.Worksheet = new Worksheet(sheetData);
//this sets the "Fit to" radio in Excel.
//note this must come before the SheetData
SheetProperties sheetProperties = new SheetProperties();
PageSetupProperties pageSetupProperties = new PageSetupProperties() { FitToPage = true };
sheetProperties.Append(pageSetupProperties);
worksheetPart.Worksheet.InsertBefore(sheetProperties, sheetData);
// this changes the fit to width and height
PageSetup pageSetup = new PageSetup() { FitToWidth = 1, FitToHeight = 43 };
worksheetPart.Worksheet.AppendChild(pageSetup);
//append the sheets / sheet
Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet()
{
Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
SheetId = 1,
Name = "Sheet1"
});
}
I am creating excel file using open xml sdk. And I want to read it using open xml. When i want to read it i am getting error at this line
SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();it return null
if I open excel file and save again.It creates shared string table and it run.
Reading from excel
#region OpenFile
public void OpenFile(string directory)
{
try
{
fs = new FileStream(directory, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
doc = SpreadsheetDocument.Open(fs, false);
}
catch (FileNotFoundException ex)
{
string exception = string.Format("Doya bulunamadı{0}", directory);
throw new ApplicationException(exception);
}
}
#endregion
#region GetWorkSheet
public void AssignWorkSheet(int sheetID)
{
if (fs == null || doc == null)
throw new ApplicationException("Dosya açılamadı");
WorkbookPart workbookPart = doc.WorkbookPart;
SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
sst = sstpart.SharedStringTable;
var workbook = workbookPart.Workbook;
var sheets = workbook.Descendants<Sheet>();
var sheetINVOICE = sheets.ElementAt(sheetID);
var worksheetPartINVOICE = (WorksheetPart)workbookPart.GetPartById(sheetINVOICE.Id);
WorkSheet = worksheetPartINVOICE.Worksheet;
//return sheetInvoice;
}
#endregion
It creates an write some text and numeric value with below code
var fileName = string.Format(#"C:\Sonuc\{0}\{1}.xlsx", systemType.ToString(), systemTypeEnum.ToString() + "_" + fileType.ToString());
SpreadsheetDocument xl = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook);
WorkbookPart wbp = xl.AddWorkbookPart();
WorksheetPart wsp = wbp.AddNewPart<WorksheetPart>();
Workbook wb = new Workbook();
FileVersion fv = new FileVersion();
fv.ApplicationName = "Microsoft Office Excel";
Worksheet ws = new Worksheet();
SheetData sd = new SheetData();
//int rowCount = 1;
DocumentFormat.OpenXml.UInt32Value rowCount = 1;
foreach (var item in resultList)
{
rowCount = rowCount + 1;
Row r3 = new Row() { RowIndex = rowCount };
Cell c6 = new Cell();
c6.DataType = CellValues.String;
c6.CellValue = new CellValue(item.BusinessPartner);
r3.Append(c6);
Cell c7 = new Cell();
c7.DataType = CellValues.Number;
c7.CellValue = new CellValue(item.VKN);
r3.Append(c7);
Cell c8 = new Cell();
c8.DataType = CellValues.Number;
c8.CellValue = new CellValue(item.InvoiceCount.ToString());
r3.Append(c8);
Cell c9 = new Cell();
c9.DataType = CellValues.Number;
c9.CellValue = new CellValue(item.TaxTotalAmount.ToString());
r3.Append(c9);
sd.Append(r3);
}
ws.Append(sd);
wsp.Worksheet = ws;
wsp.Worksheet.Save();
Sheets sheets = new Sheets();
Sheet sheet = new Sheet();
sheet.Name = "Sheet1";
sheet.SheetId = 1;
sheet.Id = wbp.GetIdOfPart(wsp);
sheets.Append(sheet);
wb.Append(fv);
wb.Append(sheets);
xl.WorkbookPart.Workbook = wb;
xl.WorkbookPart.Workbook.Save();
xl.Close();
By default, MS EXCEL saves String values using the SharedStringTablePart. It's why your code seems working when you open and save the file with MS EXCEL.
But here, when you create the file, you define the Cell.Datatype to CellValues.String (instead of CellValues.SharedString)
c6.DataType = CellValues.String;
When Cell.Datatype is CellValues.String, you must read the value by reading the Cell.CellValue property.
To save the String values using SharedStringPart, please refer to online documentation:
How to: Insert Text into a Cell in a Spreadsheet Document
How to: Retrieve the Values of Cells in a Spreadsheet Document