SpreadsheetDocumentManager.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright (c) Microsoft. All rights reserved.
  2. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Xml.Linq;
  6. using DocumentFormat.OpenXml.Packaging;
  7. namespace OpenXmlPowerTools
  8. {
  9. /// <summary>
  10. /// Manages SpreadsheetDocument content
  11. /// </summary>
  12. public class SpreadsheetDocumentManager
  13. {
  14. private static XNamespace ns;
  15. private static XNamespace relationshipsns;
  16. private static int headerRow = 1;
  17. static SpreadsheetDocumentManager()
  18. {
  19. ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
  20. relationshipsns = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
  21. }
  22. /// <summary>
  23. /// Creates a spreadsheet document from a value table
  24. /// </summary>
  25. /// <param name="filePath">Path to store the document</param>
  26. /// <param name="headerList">Contents of first row (header)</param>
  27. /// <param name="valueTable">Contents of data</param>
  28. /// <param name="initialRow">Row to start copying data from</param>
  29. /// <returns></returns>
  30. public static void Create(SpreadsheetDocument document, List<string> headerList, string[][] valueTable, int initialRow)
  31. {
  32. headerRow = initialRow;
  33. //Creates a worksheet with given data
  34. WorksheetPart worksheet = WorksheetAccessor.Create(document, headerList, valueTable, headerRow);
  35. }
  36. /// <summary>
  37. /// Creates a spreadsheet document with a chart from a value table
  38. /// </summary>
  39. /// <param name="filePath">Path to store the document</param>
  40. /// <param name="headerList">Contents of first row (header)</param>
  41. /// <param name="valueTable">Contents of data</param>
  42. /// <param name="chartType">Chart type</param>
  43. /// <param name="categoryColumn">Column to use as category for charting</param>
  44. /// <param name="columnsToChart">Columns to use as data series</param>
  45. /// <param name="initialRow">Row index to start copying data</param>
  46. /// <returns>SpreadsheetDocument</returns>
  47. //public static void Create(SpreadsheetDocument document, List<string> headerList, string[][] valueTable, ChartType chartType, string categoryColumn, List<string> columnsToChart, int initialRow)
  48. //{
  49. // headerRow = initialRow;
  50. // //Creates worksheet with data
  51. // WorksheetPart worksheet = WorksheetAccessor.Create(document, headerList, valueTable, headerRow);
  52. // //Creates chartsheet with given series and category
  53. // string sheetName = GetSheetName(worksheet, document);
  54. // ChartsheetPart chartsheet =
  55. // ChartsheetAccessor.Create(document,
  56. // chartType,
  57. // GetValueReferences(sheetName, categoryColumn, headerList, columnsToChart, valueTable),
  58. // GetHeaderReferences(sheetName, categoryColumn, headerList, columnsToChart, valueTable),
  59. // GetCategoryReference(sheetName, categoryColumn, headerList, valueTable)
  60. // );
  61. //}
  62. /// <summary>
  63. /// Gets the internal name of a worksheet from a document
  64. /// </summary>
  65. private static string GetSheetName(WorksheetPart worksheet, SpreadsheetDocument document)
  66. {
  67. //Gets the id of worksheet part
  68. string partId = document.WorkbookPart.GetIdOfPart(worksheet);
  69. XDocument workbookDocument = document.WorkbookPart.GetXDocument();
  70. //Gets the name from sheet tag related to worksheet
  71. string sheetName =
  72. workbookDocument.Root
  73. .Element(ns + "sheets")
  74. .Elements(ns + "sheet")
  75. .Where(
  76. t =>
  77. t.Attribute(relationshipsns + "id").Value == partId
  78. ).First()
  79. .Attribute("name").Value;
  80. return sheetName;
  81. }
  82. /// <summary>
  83. /// Gets the range reference for category
  84. /// </summary>
  85. /// <param name="sheetName">worksheet to take data from</param>
  86. /// <param name="headerColumn">name of column used as category</param>
  87. /// <param name="headerList">column names from data</param>
  88. /// <param name="valueTable">Data values</param>
  89. /// <returns></returns>
  90. private static string GetCategoryReference(string sheetName, string headerColumn, List<string> headerList, string[][] valueTable)
  91. {
  92. int categoryColumn = headerList.IndexOf(headerColumn.ToUpper()) + 1;
  93. int numRows = valueTable.GetLength(0);
  94. return GetRangeReference(
  95. sheetName,
  96. categoryColumn,
  97. headerRow + 1,
  98. categoryColumn,
  99. numRows + headerRow
  100. );
  101. }
  102. /// <summary>
  103. /// Gets a list of range references for each of the series headers
  104. /// </summary>
  105. /// <param name="sheetName">worksheet to take data from</param>
  106. /// <param name="headerColumn">name of column used as category</param>
  107. /// <param name="headerList">column names from data</param>
  108. /// <param name="valueTable">Data values</param>
  109. /// <param name="colsToChart">Columns used as data series</param>
  110. /// <returns></returns>
  111. private static List<string> GetHeaderReferences(string sheetName, string headerColumn, List<string> headerList, List<string> colsToChart, string[][] valueTable)
  112. {
  113. List<string> valueReferenceList = new List<string>();
  114. foreach (string column in colsToChart)
  115. {
  116. valueReferenceList.Add(
  117. GetRangeReference(
  118. sheetName,
  119. headerList.IndexOf(column.ToUpper()) + 1,
  120. headerRow
  121. )
  122. );
  123. }
  124. return valueReferenceList;
  125. }
  126. /// <summary>
  127. /// Gets a list of range references for each of the series values
  128. /// </summary>
  129. /// <param name="sheetName">worksheet to take data from</param>
  130. /// <param name="headerColumn">name of column used as category</param>
  131. /// <param name="headerList">column names from data</param>
  132. /// <param name="valueTable">Data values</param>
  133. /// <param name="colsToChart">Columns used as data series</param>
  134. /// <returns></returns>
  135. private static List<string> GetValueReferences(string sheetName, string headerColumn, List<string> headerList, List<string> colsToChart, string[][] valueTable)
  136. {
  137. List<string> valueReferenceList = new List<string>();
  138. int numRows = valueTable.GetLength(0);
  139. foreach (string column in colsToChart)
  140. {
  141. int dataColumn = headerList.IndexOf(column.ToUpper()) + 1;
  142. valueReferenceList.Add(
  143. GetRangeReference(
  144. sheetName,
  145. dataColumn,
  146. headerRow + 1,
  147. dataColumn,
  148. numRows + headerRow
  149. )
  150. );
  151. }
  152. return valueReferenceList;
  153. }
  154. /// <summary>
  155. /// Gets a formatted representation of a cell range from a worksheet
  156. /// </summary>
  157. private static string GetRangeReference(string worksheet, int column, int row)
  158. {
  159. return string.Format("{0}!{1}{2}", worksheet, WorksheetAccessor.GetColumnId(column), row);
  160. }
  161. /// <summary>
  162. /// Gets a formatted representation of a cell range from a worksheet
  163. /// </summary>
  164. private static string GetRangeReference(string worksheet, int startColumn, int startRow, int endColumn, int endRow)
  165. {
  166. return string.Format("{0}!{1}{2}:{3}{4}",
  167. worksheet,
  168. WorksheetAccessor.GetColumnId(startColumn),
  169. startRow,
  170. WorksheetAccessor.GetColumnId(endColumn),
  171. endRow
  172. );
  173. }
  174. /// <summary>
  175. /// Creates an empty (base) workbook document
  176. /// </summary>
  177. /// <returns></returns>
  178. private static XDocument CreateEmptyWorkbook()
  179. {
  180. XDocument document =
  181. new XDocument(
  182. new XElement(ns + "workbook",
  183. new XAttribute("xmlns", ns),
  184. new XAttribute(XNamespace.Xmlns + "r", relationshipsns),
  185. new XElement(ns + "sheets")
  186. )
  187. );
  188. return document;
  189. }
  190. }
  191. }