// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
namespace OpenXmlPowerTools
{
///
/// Manages SpreadsheetDocument content
///
public class SpreadsheetDocumentManager
{
private static XNamespace ns;
private static XNamespace relationshipsns;
private static int headerRow = 1;
static SpreadsheetDocumentManager()
{
ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
relationshipsns = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
}
///
/// Creates a spreadsheet document from a value table
///
/// Path to store the document
/// Contents of first row (header)
/// Contents of data
/// Row to start copying data from
///
public static void Create(SpreadsheetDocument document, List headerList, string[][] valueTable, int initialRow)
{
headerRow = initialRow;
//Creates a worksheet with given data
WorksheetPart worksheet = WorksheetAccessor.Create(document, headerList, valueTable, headerRow);
}
///
/// Creates a spreadsheet document with a chart from a value table
///
/// Path to store the document
/// Contents of first row (header)
/// Contents of data
/// Chart type
/// Column to use as category for charting
/// Columns to use as data series
/// Row index to start copying data
/// SpreadsheetDocument
//public static void Create(SpreadsheetDocument document, List headerList, string[][] valueTable, ChartType chartType, string categoryColumn, List columnsToChart, int initialRow)
//{
// headerRow = initialRow;
// //Creates worksheet with data
// WorksheetPart worksheet = WorksheetAccessor.Create(document, headerList, valueTable, headerRow);
// //Creates chartsheet with given series and category
// string sheetName = GetSheetName(worksheet, document);
// ChartsheetPart chartsheet =
// ChartsheetAccessor.Create(document,
// chartType,
// GetValueReferences(sheetName, categoryColumn, headerList, columnsToChart, valueTable),
// GetHeaderReferences(sheetName, categoryColumn, headerList, columnsToChart, valueTable),
// GetCategoryReference(sheetName, categoryColumn, headerList, valueTable)
// );
//}
///
/// Gets the internal name of a worksheet from a document
///
private static string GetSheetName(WorksheetPart worksheet, SpreadsheetDocument document)
{
//Gets the id of worksheet part
string partId = document.WorkbookPart.GetIdOfPart(worksheet);
XDocument workbookDocument = document.WorkbookPart.GetXDocument();
//Gets the name from sheet tag related to worksheet
string sheetName =
workbookDocument.Root
.Element(ns + "sheets")
.Elements(ns + "sheet")
.Where(
t =>
t.Attribute(relationshipsns + "id").Value == partId
).First()
.Attribute("name").Value;
return sheetName;
}
///
/// Gets the range reference for category
///
/// worksheet to take data from
/// name of column used as category
/// column names from data
/// Data values
///
private static string GetCategoryReference(string sheetName, string headerColumn, List headerList, string[][] valueTable)
{
int categoryColumn = headerList.IndexOf(headerColumn.ToUpper()) + 1;
int numRows = valueTable.GetLength(0);
return GetRangeReference(
sheetName,
categoryColumn,
headerRow + 1,
categoryColumn,
numRows + headerRow
);
}
///
/// Gets a list of range references for each of the series headers
///
/// worksheet to take data from
/// name of column used as category
/// column names from data
/// Data values
/// Columns used as data series
///
private static List GetHeaderReferences(string sheetName, string headerColumn, List headerList, List colsToChart, string[][] valueTable)
{
List valueReferenceList = new List();
foreach (string column in colsToChart)
{
valueReferenceList.Add(
GetRangeReference(
sheetName,
headerList.IndexOf(column.ToUpper()) + 1,
headerRow
)
);
}
return valueReferenceList;
}
///
/// Gets a list of range references for each of the series values
///
/// worksheet to take data from
/// name of column used as category
/// column names from data
/// Data values
/// Columns used as data series
///
private static List GetValueReferences(string sheetName, string headerColumn, List headerList, List colsToChart, string[][] valueTable)
{
List valueReferenceList = new List();
int numRows = valueTable.GetLength(0);
foreach (string column in colsToChart)
{
int dataColumn = headerList.IndexOf(column.ToUpper()) + 1;
valueReferenceList.Add(
GetRangeReference(
sheetName,
dataColumn,
headerRow + 1,
dataColumn,
numRows + headerRow
)
);
}
return valueReferenceList;
}
///
/// Gets a formatted representation of a cell range from a worksheet
///
private static string GetRangeReference(string worksheet, int column, int row)
{
return string.Format("{0}!{1}{2}", worksheet, WorksheetAccessor.GetColumnId(column), row);
}
///
/// Gets a formatted representation of a cell range from a worksheet
///
private static string GetRangeReference(string worksheet, int startColumn, int startRow, int endColumn, int endRow)
{
return string.Format("{0}!{1}{2}:{3}{4}",
worksheet,
WorksheetAccessor.GetColumnId(startColumn),
startRow,
WorksheetAccessor.GetColumnId(endColumn),
endRow
);
}
///
/// Creates an empty (base) workbook document
///
///
private static XDocument CreateEmptyWorkbook()
{
XDocument document =
new XDocument(
new XElement(ns + "workbook",
new XAttribute("xmlns", ns),
new XAttribute(XNamespace.Xmlns + "r", relationshipsns),
new XElement(ns + "sheets")
)
);
return document;
}
}
}