PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/1.45/App_Code/ExcelExporter.cs

#
C# | 181 lines | 164 code | 8 blank | 9 comment | 21 complexity | 9d833c43d1959891f3b27ddb8ff6d6b9 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using Yogesh.ExcelXml;
  6. using System.Data.Common;
  7. using System.Data;
  8. using System.IO;
  9. using ICSharpCode.SharpZipLib.Zip;
  10. using System.Text;
  11. //TODO: Add another sheet with help for translators
  12. /// <summary>
  13. /// Exports selected forms and languages to an Excel XML spreadsheet
  14. /// </summary>
  15. public static class ExcelExporter
  16. {
  17. /// <summary>
  18. /// Generates, then sends an XML spreadsheet to the browser based on the inputs on the previous page
  19. /// </summary>
  20. public static string ExportToExcel(string[] applicationIds, string[] selectedLanguages, string[] selectedBundles, bool zipOutput) {
  21. Database db = null;
  22. string error = string.Empty;
  23. try {
  24. db = new Database();
  25. db.OpenConnection();
  26. ExcelXmlWorkbook wb = new ExcelXmlWorkbook();
  27. List<int> addedIds = new List<int>();
  28. wb.Properties.Title = "ResourceBlender Resources (" + DateTime.Now.ToString("yyyy-MM-dd-HHmm") + ")";
  29. using(Database.Command cmdApplication = db.CreateCommand())
  30. using(Database.Command cmdResources = db.CreateCommand()) {
  31. cmdApplication.CommandText = "SELECT displayname, defaultLanguage, languages FROM " + db.TablePrefix + "applications WHERE id = @p";
  32. cmdApplication.AddParameterWithValue("@p", "");
  33. cmdResources.AddParameterWithValue("@p", "");
  34. string applicationId = null,
  35. applicationName = null,
  36. defaultLanguage = null;
  37. string[] allLanguagesInApplication = null;
  38. int startingColumn = 1;
  39. List<string> selectedLanguagesInApplication = new List<string>(); // if just one list of languages is used, there are gaps for columns where a language from another application is not present in the current application
  40. XmlStyle greenBackground = new XmlStyle(),
  41. greyBackground = new XmlStyle();
  42. greenBackground.Interior.Color = System.Drawing.Color.FromArgb(234, 241, 221);
  43. greenBackground.Interior.Pattern = Pattern.Solid;
  44. greyBackground.Interior.Color = System.Drawing.Color.FromArgb(240, 240, 240);
  45. greyBackground.Interior.Pattern = Pattern.Solid;
  46. greyBackground.Font.Color = System.Drawing.Color.FromArgb(130, 130, 130);
  47. for(int i=0;i<applicationIds.Length;i++) {
  48. selectedLanguagesInApplication.Clear();
  49. applicationId = applicationIds[i];
  50. cmdApplication.Parameters["@p"].Value = applicationId;
  51. cmdResources.Parameters["@p"].Value = applicationId;
  52. using(DbDataReader reader = cmdApplication.ExecuteReader(CommandBehavior.SingleResult)) {
  53. while(reader.Read()) {
  54. applicationName = reader.GetString(0);
  55. defaultLanguage = reader.GetString(1);
  56. allLanguagesInApplication = reader.GetString(2).Trim().Split(',');
  57. }
  58. reader.Close();
  59. }
  60. if(applicationName == null || applicationName.Length == 0) {
  61. throw new ArgumentNullException("Application not found");
  62. }
  63. selectedLanguagesInApplication.Add(defaultLanguage);
  64. int rowIndex = 1;
  65. Worksheet sheet = wb[i];
  66. sheet.Name = applicationName;
  67. Row row = sheet.AddRow();
  68. int column = startingColumn + 1;
  69. sheet[startingColumn, 0].Value = "Resource ID";
  70. Cell headerCell = sheet[column++, 0];
  71. headerCell.Value = defaultLanguage;
  72. foreach(string lang in allLanguagesInApplication) {
  73. if(selectedLanguages.Contains(lang)) {
  74. if(lang != defaultLanguage) {
  75. selectedLanguagesInApplication.Add(lang);
  76. headerCell = sheet[column++, 0];
  77. headerCell.Value = lang;
  78. }
  79. }
  80. }
  81. sheet.FreezeTopRows = 1;
  82. if(selectedLanguagesInApplication.Count == 0) {
  83. throw new ArgumentException("No languages found for appliication:" + applicationName);
  84. }
  85. //sheet.Table.Columns[startingColumn].Width = 200;
  86. cmdResources.CommandText = new StringBuilder("SELECT DISTINCT e.resourceid, e.id, r.language, r.translation, r.translatorcomment, c.comment FROM ")
  87. .Append(db.TablePrefix).Append("elements AS e INNER JOIN ").Append(db.TablePrefix).Append("resources AS r ON r.resourceid = e.resourceid LEFT JOIN ")
  88. .Append(db.TablePrefix).Append("resourcecomments AS c ON c.resourceid = r.resourceid WHERE applicationid = @p AND language IN('")
  89. .Append(Utils.Implode(selectedLanguagesInApplication, "','", false)).Append("') AND bundle IN('").Append(Utils.Implode(selectedBundles, "','", false)).Append("') ORDER BY e.id").ToString();
  90. using(DbDataReader reader = cmdResources.ExecuteReader()) {
  91. int lastIdRead = -1;
  92. while(reader.Read()) {
  93. int resourceId = int.Parse(reader["resourceid"].ToString());
  94. Cell cell = null;
  95. if(lastIdRead == -1) {
  96. if(addedIds.Contains(resourceId)) {
  97. continue;
  98. }
  99. addedIds.Add(resourceId);
  100. lastIdRead = resourceId;
  101. cell = sheet[startingColumn, rowIndex];
  102. cell.Value = resourceId;
  103. cell.Comment = reader["comment"].ToString().Replace("<", "&lt;").Replace(">", "&gt;");
  104. cell.Style = greyBackground;
  105. } else if(lastIdRead != resourceId) {
  106. if(addedIds.Contains(resourceId)) {
  107. continue;
  108. }
  109. addedIds.Add(resourceId);
  110. lastIdRead = resourceId;
  111. cell = sheet[startingColumn, ++rowIndex];
  112. cell.Value = resourceId;
  113. cell.Comment = reader["comment"].ToString().Replace("<", "&lt;").Replace(">", "&gt;");
  114. cell.Style = greyBackground;
  115. }
  116. cell = sheet[selectedLanguagesInApplication.IndexOf(reader["language"].ToString()) + startingColumn + 1, rowIndex];
  117. //System.Diagnostics.Debug.WriteLine(reader["language"].ToString()+"\t"+selectedLanguagesInApplication.IndexOf(reader["language"].ToString())+"\t"+selectedLanguagesInApplication.IndexOf(reader["language"].ToString()) + startingColumn + 1);
  118. cell.Value = reader["translation"].ToString().Replace("<", "&lt;").Replace(">", "&gt;"); //HttpUtility.HtmlEncode(reader["translation"].ToString());
  119. cell.Comment = reader["translatorcomment"].ToString().Replace("<", "&lt;").Replace(">", "&gt;");
  120. }
  121. reader.Close();
  122. }
  123. Range defaultColumn = new Range(sheet[startingColumn + 1, 0], sheet[startingColumn + 1, rowIndex]);
  124. defaultColumn.Style = greenBackground;
  125. Range headerCells = new Range(sheet[startingColumn, 0], sheet[column, 0]);
  126. headerCells.Font.Bold = true;
  127. }
  128. }
  129. HttpResponse res = HttpContext.Current.Response;
  130. using(MemoryStream msXml = new MemoryStream()) { // holding stream for workbook
  131. string fileName = "ResourceBlender" + DateTime.Now.ToString("yyyy-MM-dd-HHmm");
  132. if(zipOutput) {
  133. using(MemoryStream msZip = new MemoryStream()) { // output stream for zip
  134. ZipOutputStream zipStream = new ZipOutputStream(msZip);
  135. zipStream.SetLevel(9);
  136. wb.Export(msXml);
  137. byte[] buffer = msXml.ToArray();
  138. msXml.Close();
  139. ZipEntry zipEntry = new ZipEntry(fileName + ".xml");
  140. zipEntry.DateTime = DateTime.Now;
  141. zipEntry.Size = buffer.Length;
  142. zipStream.PutNextEntry(zipEntry);
  143. zipStream.Write(buffer, 0, buffer.Length);
  144. zipStream.Finish();
  145. res.Clear();
  146. res.AddHeader("Content-Type", "binary/octet-stream");
  147. res.AddHeader("Content-Length", zipStream.Length.ToString());
  148. res.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".zip\"; size=" + zipStream.Length.ToString());
  149. res.Flush();
  150. res.BinaryWrite(msZip.ToArray());
  151. msZip.Close();
  152. }
  153. } else {
  154. wb.Export(msXml);
  155. res.Clear();
  156. res.AddHeader("Content-Type", "binary/octet-stream");
  157. res.AddHeader("Content-Length", msXml.Length.ToString());
  158. res.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xml\"; size=" + msXml.Length.ToString()); // todo: include date in filename
  159. msXml.WriteTo(res.OutputStream);
  160. }
  161. res.Flush();
  162. res.End();
  163. }
  164. } catch(Exception ex) {
  165. error = ex.Message + ex.StackTrace;
  166. } finally {
  167. if(db != null) {
  168. db.CloseConnection();
  169. }
  170. }
  171. return error;
  172. }
  173. }