mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Improves "save as Excel" functionality (#2266)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Xml;
|
||||
@@ -75,21 +76,31 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
// new TimeSpan(24,0,0).Ticks
|
||||
private const long TicksPerDay = 864000000000L;
|
||||
|
||||
// Digit pixel width for 11 point Calibri
|
||||
private const float FontPixelWidth = 7;
|
||||
|
||||
private XmlWriter writer;
|
||||
private ReferenceManager referenceManager;
|
||||
private bool hasOpenRowTag;
|
||||
|
||||
private readonly int columnCount;
|
||||
private bool autoFilterColumns;
|
||||
private bool hasStartedSheetData;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ExcelSheet class.
|
||||
/// </summary>
|
||||
/// <param name="writer">XmlWriter to write the sheet data</param>
|
||||
internal ExcelSheet(XmlWriter writer)
|
||||
/// <param name="columnCount">Number of columns in the new sheet</param>
|
||||
internal ExcelSheet(XmlWriter writer, int columnCount)
|
||||
{
|
||||
this.writer = writer;
|
||||
this.columnCount = columnCount;
|
||||
|
||||
writer.WriteStartDocument();
|
||||
writer.WriteStartElement("worksheet", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
writer.WriteAttributeString("xmlns", "r", null, "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
||||
writer.WriteStartElement("sheetData");
|
||||
|
||||
referenceManager = new ReferenceManager(writer);
|
||||
}
|
||||
|
||||
@@ -98,6 +109,13 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// </summary>
|
||||
public void AddRow()
|
||||
{
|
||||
// Write the open tag for sheetData if it hasn't been written yet
|
||||
if (!hasStartedSheetData)
|
||||
{
|
||||
writer.WriteStartElement("sheetData");
|
||||
hasStartedSheetData = true;
|
||||
}
|
||||
|
||||
EndRowIfNeeded();
|
||||
hasOpenRowTag = true;
|
||||
|
||||
@@ -110,8 +128,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <summary>
|
||||
/// Write a string cell
|
||||
/// </summary>
|
||||
/// <param name="value">string value to write</param>
|
||||
public void AddCell(string value)
|
||||
/// <param name="value">String value to write</param>
|
||||
/// <param name="bold">Whether the cell should be bold, defaults to false</param>
|
||||
public void AddCell(string value, bool bold = false)
|
||||
{
|
||||
// string needs <c t="inlineStr"><is><t>string</t></is></c>
|
||||
// This class uses inlineStr instead of more common shared string table
|
||||
@@ -129,21 +148,28 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
|
||||
writer.WriteAttributeString("t", "inlineStr");
|
||||
|
||||
// Write the style attribute set to the bold font if requested
|
||||
if (bold)
|
||||
{
|
||||
writer.WriteAttributeString("s", "5");
|
||||
}
|
||||
|
||||
writer.WriteStartElement("is");
|
||||
writer.WriteStartElement("t");
|
||||
writer.WriteValue(value);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <t>
|
||||
writer.WriteEndElement(); // <is>
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <c>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a object cell
|
||||
/// </summary>
|
||||
/// The program will try to output number/datetime, otherwise, call the ToString
|
||||
/// <param name="o"></param>
|
||||
public void AddCell(DbCellValue dbCellValue)
|
||||
/// <param name="dbCellValue">DbCellValue to write based on data type</param>
|
||||
/// <param name="bold">Whether the cell should be bold, defaults to false</param>
|
||||
public void AddCell(DbCellValue dbCellValue, bool bold = false)
|
||||
{
|
||||
object o = dbCellValue.RawObject;
|
||||
if (dbCellValue.IsNull || o == null)
|
||||
@@ -169,25 +195,100 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
AddCell((DateTime)o);
|
||||
break;
|
||||
case TypeCode.String:
|
||||
AddCell((string)o);
|
||||
AddCell((string)o, bold);
|
||||
break;
|
||||
default:
|
||||
if (o is TimeSpan span) //TimeSpan doesn't have TypeCode
|
||||
{
|
||||
AddCell(span);
|
||||
}
|
||||
// We need to handle SqlDecimal and SqlMoney types here because we can't convert them to .NET types due to different precisons in SQL Server and .NET.
|
||||
// We need to handle SqlDecimal and SqlMoney types here because we can't convert them to .NET types due to different precisions in SQL Server and .NET.
|
||||
else if (o is SqlDecimal || o is SqlMoney)
|
||||
{
|
||||
AddCellBoxedNumber(dbCellValue.DisplayValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddCell(dbCellValue.DisplayValue);
|
||||
AddCell(dbCellValue.DisplayValue, bold);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a sheetView that freezes the top row. Must be called before any rows have been added.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown if called after any rows have been added.</exception>
|
||||
public void FreezeHeaderRow()
|
||||
{
|
||||
if (hasStartedSheetData)
|
||||
{
|
||||
throw new InvalidOperationException("Must be called before calling AddRow");
|
||||
}
|
||||
|
||||
writer.WriteStartElement("sheetViews");
|
||||
|
||||
writer.WriteStartElement("sheetView");
|
||||
writer.WriteAttributeString("tabSelected", "1");
|
||||
writer.WriteAttributeString("workbookViewId", "0");
|
||||
|
||||
writer.WriteStartElement("pane");
|
||||
writer.WriteAttributeString("ySplit", "1");
|
||||
writer.WriteAttributeString("topLeftCell", "A2");
|
||||
writer.WriteAttributeString("activePane", "bottomLeft");
|
||||
writer.WriteAttributeString("state", "frozen");
|
||||
writer.WriteEndElement(); // <pane>
|
||||
|
||||
writer.WriteStartElement("selection");
|
||||
writer.WriteAttributeString("pane", "bottomLeft");
|
||||
writer.WriteEndElement(); // <selection>
|
||||
|
||||
writer.WriteEndElement(); // <sheetView>
|
||||
writer.WriteEndElement(); // <sheetViews>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable auto filtering, the XML will be written when closing the sheet later
|
||||
/// </summary>
|
||||
public void EnableAutoFilter()
|
||||
{
|
||||
autoFilterColumns = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the columns widths. Must be called before any rows have been added.
|
||||
/// </summary>
|
||||
/// <param name="columnWidths">Array with the widths of each column.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown if called after any rows have been added.</exception>
|
||||
public void WriteColumnInformation(float[] columnWidths)
|
||||
{
|
||||
if (hasStartedSheetData)
|
||||
{
|
||||
throw new InvalidOperationException("Must be called before calling AddRow");
|
||||
}
|
||||
|
||||
if (columnWidths.Length != this.columnCount)
|
||||
{
|
||||
throw new InvalidOperationException("Column count mismatch");
|
||||
}
|
||||
|
||||
writer.WriteStartElement("cols");
|
||||
|
||||
for (int columnIndex = 0; columnIndex < columnWidths.Length; columnIndex++)
|
||||
{
|
||||
var columnWidth = Math.Truncate((columnWidths[columnIndex] + 15) / FontPixelWidth * 256) / 256;
|
||||
|
||||
writer.WriteStartElement("col");
|
||||
writer.WriteAttributeString("min", (columnIndex + 1).ToString());
|
||||
writer.WriteAttributeString("max", (columnIndex + 1).ToString());
|
||||
writer.WriteAttributeString("width", columnWidth.ToString(CultureInfo.InvariantCulture));
|
||||
writer.WriteAttributeString("bestFit", "1");
|
||||
writer.WriteAttributeString("customWidth", "1");
|
||||
writer.WriteEndElement(); // <col>
|
||||
}
|
||||
|
||||
writer.WriteEndElement(); // <cols>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the <row><sheetData><worksheet> tags and close the stream
|
||||
@@ -196,6 +297,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
{
|
||||
EndRowIfNeeded();
|
||||
writer.WriteEndElement(); // <sheetData>
|
||||
|
||||
// Write the auto filter XML if requested
|
||||
if (autoFilterColumns)
|
||||
{
|
||||
writer.WriteStartElement("autoFilter");
|
||||
writer.WriteAttributeString("ref", $"A1:{ReferenceManager.GetColumnName(this.columnCount)}1");
|
||||
writer.WriteEndElement(); // <autoFilter>
|
||||
}
|
||||
|
||||
writer.WriteEndElement(); // <worksheet>
|
||||
writer.Dispose();
|
||||
}
|
||||
@@ -203,7 +313,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <summary>
|
||||
/// Write a empty cell
|
||||
/// </summary>
|
||||
/// This only increases the internal bookmark and doesn't arcturally write out anything.
|
||||
/// This only increases the internal bookmark and doesn't actually write out anything.
|
||||
private void AddCellEmpty()
|
||||
{
|
||||
referenceManager.IncreaseColumnReference();
|
||||
@@ -212,7 +322,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <summary>
|
||||
/// Write a bool cell.
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <param name="value">Boolean value to write</param>
|
||||
private void AddCell(bool value)
|
||||
{
|
||||
// Excel FALSE: <c r="A1" t="b"><v>0</v></c>
|
||||
@@ -234,15 +344,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
{
|
||||
writer.WriteValue("0");
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <v>
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <c>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a TimeSpan cell.
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <param name="time">TimeSpan value to write</param>
|
||||
private void AddCell(TimeSpan time)
|
||||
{
|
||||
referenceManager.AssureColumnReference();
|
||||
@@ -262,7 +372,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <summary>
|
||||
/// Write a DateTime cell.
|
||||
/// </summary>
|
||||
/// <param name="dateTime">Datetime</param>
|
||||
/// <param name="dateTime">DateTime value to write</param>
|
||||
/// <remark>
|
||||
/// If the DateTime does not have date part, it will be written as datetime and show as time only
|
||||
/// If the DateTime is before 1900-03-01, save as string because excel doesn't support them.
|
||||
@@ -307,9 +417,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
|
||||
writer.WriteStartElement("v");
|
||||
writer.WriteValue(number);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <v>
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <c>
|
||||
}
|
||||
|
||||
|
||||
@@ -326,9 +436,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
|
||||
writer.WriteStartElement("v");
|
||||
writer.WriteValue(excelDate);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <v>
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // <c>
|
||||
}
|
||||
|
||||
private void EndRowIfNeeded()
|
||||
@@ -338,8 +448,6 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
writer.WriteEndElement(); // <row>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -429,6 +537,26 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the column name (letters) from a column number
|
||||
/// https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-e-g-127-into-an-excel-column-e-g-aa
|
||||
/// </summary>
|
||||
/// <param name="columnNumber">The column number.</param>
|
||||
/// <returns>The column name.</returns>
|
||||
public static string GetColumnName(int columnNumber)
|
||||
{
|
||||
string columnName = "";
|
||||
|
||||
while (columnNumber > 0)
|
||||
{
|
||||
int modulo = (columnNumber - 1) % 26;
|
||||
columnName = Convert.ToChar('A' + modulo) + columnName;
|
||||
columnNumber = (columnNumber - modulo) / 26;
|
||||
}
|
||||
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that we have not write too many rows. (xlsx has a limit of 1048576 rows)
|
||||
/// </summary>
|
||||
@@ -511,11 +639,11 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <param name="sheetName">Sheet name</param>
|
||||
/// <returns>ExcelSheet for writing the sheet content</returns>
|
||||
/// <remarks>
|
||||
/// When the sheetName is null, sheet1,shhet2,..., will be used.
|
||||
/// The following charactors are not allowed in the sheetName
|
||||
/// When the sheetName is null, sheet1,sheet2,..., will be used.
|
||||
/// The following characters are not allowed in the sheetName
|
||||
/// '\', '/','*','[',']',':','?'
|
||||
/// </remarks>
|
||||
public ExcelSheet AddSheet(string sheetName = null)
|
||||
public ExcelSheet AddSheet(string sheetName, int columnCount)
|
||||
{
|
||||
string sheetFileName = "sheet" + (sheetNames.Count + 1);
|
||||
sheetName ??= sheetFileName;
|
||||
@@ -523,7 +651,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
|
||||
sheetNames.Add(sheetName);
|
||||
XmlWriter sheetWriter = AddEntry($"xl/worksheets/{sheetFileName}.xml");
|
||||
return new ExcelSheet(sheetWriter);
|
||||
return new ExcelSheet(sheetWriter, columnCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -568,26 +696,26 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteStartElement("Default");
|
||||
xw.WriteAttributeString("Extension", "rels");
|
||||
xw.WriteAttributeString("ContentType", "application/vnd.openxmlformats-package.relationships+xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Default>
|
||||
|
||||
xw.WriteStartElement("Override");
|
||||
xw.WriteAttributeString("PartName", "/xl/workbook.xml");
|
||||
xw.WriteAttributeString("ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Override>
|
||||
|
||||
xw.WriteStartElement("Override");
|
||||
xw.WriteAttributeString("PartName", "/xl/styles.xml");
|
||||
xw.WriteAttributeString("ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Override>
|
||||
|
||||
for (int i = 1; i <= sheetNames.Count; ++i)
|
||||
{
|
||||
xw.WriteStartElement("Override");
|
||||
xw.WriteAttributeString("PartName", "/xl/worksheets/sheet" + i + ".xml");
|
||||
xw.WriteAttributeString("ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Override>
|
||||
}
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Types>
|
||||
xw.WriteEndDocument();
|
||||
}
|
||||
}
|
||||
@@ -607,9 +735,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("Id", "rId1");
|
||||
xw.WriteAttributeString("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
|
||||
xw.WriteAttributeString("Target", "xl/workbook.xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Relationship>
|
||||
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Relationships>
|
||||
|
||||
xw.WriteEndDocument();
|
||||
}
|
||||
@@ -648,7 +776,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("name", sheetNames[i - 1]);
|
||||
xw.WriteAttributeString("sheetId", i.ToString());
|
||||
xw.WriteAttributeString("r", "id", null, "rId" + i);
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <sheet>
|
||||
}
|
||||
xw.WriteEndDocument();
|
||||
}
|
||||
@@ -668,7 +796,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("Id", "rId0");
|
||||
xw.WriteAttributeString("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles");
|
||||
xw.WriteAttributeString("Target", "styles.xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Relationship>
|
||||
|
||||
for (int i = 1; i <= sheetNames.Count; i++)
|
||||
{
|
||||
@@ -676,9 +804,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("Id", "rId" + i);
|
||||
xw.WriteAttributeString("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet");
|
||||
xw.WriteAttributeString("Target", "worksheets/sheet" + i + ".xml");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Relationship>
|
||||
}
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <Relationships>
|
||||
xw.WriteEndDocument();
|
||||
}
|
||||
}
|
||||
@@ -702,41 +830,63 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteStartElement("numFmt");
|
||||
xw.WriteAttributeString("numFmtId", "166");
|
||||
xw.WriteAttributeString("formatCode", "yyyy-mm-dd");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <numFmt>
|
||||
xw.WriteStartElement("numFmt");
|
||||
xw.WriteAttributeString("numFmtId", "167");
|
||||
xw.WriteAttributeString("formatCode", "hh:mm:ss");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <numFmt>
|
||||
xw.WriteStartElement("numFmt");
|
||||
xw.WriteAttributeString("numFmtId", "168");
|
||||
xw.WriteAttributeString("formatCode", "yyyy-mm-dd hh:mm:ss");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <numFmt>
|
||||
xw.WriteStartElement("numFmt");
|
||||
xw.WriteAttributeString("numFmtId", "169");
|
||||
xw.WriteAttributeString("formatCode", "[h]:mm:ss");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); //mumFmts
|
||||
xw.WriteEndElement(); // <numFmt>
|
||||
xw.WriteEndElement(); // <numFmts>
|
||||
|
||||
|
||||
xw.WriteStartElement("fonts");
|
||||
xw.WriteAttributeString("count", "1");
|
||||
xw.WriteAttributeString("count", "2");
|
||||
|
||||
xw.WriteStartElement("font");
|
||||
xw.WriteStartElement("sz");
|
||||
xw.WriteAttributeString("val", "11");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <sz>
|
||||
xw.WriteStartElement("color");
|
||||
xw.WriteAttributeString("theme", "1");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <color>
|
||||
xw.WriteStartElement("name");
|
||||
xw.WriteAttributeString("val", "Calibri");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <name>
|
||||
xw.WriteStartElement("family");
|
||||
xw.WriteAttributeString("val", "2");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <family>
|
||||
xw.WriteStartElement("scheme");
|
||||
xw.WriteAttributeString("val", "minor");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // font
|
||||
xw.WriteEndElement(); // <scheme>
|
||||
xw.WriteEndElement(); // <font>
|
||||
|
||||
xw.WriteStartElement("font");
|
||||
xw.WriteStartElement("b");
|
||||
xw.WriteEndElement(); // <b>
|
||||
xw.WriteStartElement("sz");
|
||||
xw.WriteAttributeString("val", "11");
|
||||
xw.WriteEndElement(); // <sz>
|
||||
xw.WriteStartElement("color");
|
||||
xw.WriteAttributeString("theme", "1");
|
||||
xw.WriteEndElement(); // <color>
|
||||
xw.WriteStartElement("name");
|
||||
xw.WriteAttributeString("val", "Calibri");
|
||||
xw.WriteEndElement(); // <name>
|
||||
xw.WriteStartElement("family");
|
||||
xw.WriteAttributeString("val", "2");
|
||||
xw.WriteEndElement(); // <family>
|
||||
xw.WriteStartElement("scheme");
|
||||
xw.WriteAttributeString("val", "minor");
|
||||
xw.WriteEndElement(); // <scheme>
|
||||
xw.WriteEndElement(); // <font>
|
||||
|
||||
xw.WriteEndElement(); // fonts
|
||||
|
||||
xw.WriteStartElement("fills");
|
||||
@@ -744,9 +894,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteStartElement("fill");
|
||||
xw.WriteStartElement("patternFill");
|
||||
xw.WriteAttributeString("patternType", "none");
|
||||
xw.WriteEndElement(); // patternFill
|
||||
xw.WriteEndElement(); // fill
|
||||
xw.WriteEndElement(); // fills
|
||||
xw.WriteEndElement(); // <patternFill>
|
||||
xw.WriteEndElement(); // <fill>
|
||||
xw.WriteEndElement(); // <fills>
|
||||
|
||||
xw.WriteStartElement("borders");
|
||||
xw.WriteAttributeString("count", "1");
|
||||
@@ -756,8 +906,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteElementString("top", null);
|
||||
xw.WriteElementString("bottom", null);
|
||||
xw.WriteElementString("diagonal", null);
|
||||
xw.WriteEndElement(); // board
|
||||
xw.WriteEndElement(); // borders
|
||||
xw.WriteEndElement(); // <border>
|
||||
xw.WriteEndElement(); // <borders>
|
||||
|
||||
xw.WriteStartElement("cellStyleXfs");
|
||||
xw.WriteAttributeString("count", "1");
|
||||
@@ -766,35 +916,39 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("fontId", "0");
|
||||
xw.WriteAttributeString("fillId", "0");
|
||||
xw.WriteAttributeString("borderId", "0");
|
||||
xw.WriteEndElement(); // xf
|
||||
xw.WriteEndElement(); // cellStyleXfs
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteEndElement(); // <cellStyleXfs>
|
||||
|
||||
xw.WriteStartElement("cellXfs");
|
||||
xw.WriteAttributeString("count", "5");
|
||||
xw.WriteAttributeString("count", "6");
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("numFmtId", "166");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteAttributeString("applyNumberFormat", "1");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("numFmtId", "167");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteAttributeString("applyNumberFormat", "1");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("numFmtId", "168");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteAttributeString("applyNumberFormat", "1");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("numFmtId", "169");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteAttributeString("applyNumberFormat", "1");
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndElement(); // cellXfs
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteStartElement("xf");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteAttributeString("fontId", "1");
|
||||
xw.WriteEndElement(); // <xf>
|
||||
xw.WriteEndElement(); // <cellXfs>
|
||||
|
||||
xw.WriteStartElement("cellStyles");
|
||||
xw.WriteAttributeString("count", "1");
|
||||
@@ -802,8 +956,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
xw.WriteAttributeString("name", "Normal");
|
||||
xw.WriteAttributeString("builtinId", "0");
|
||||
xw.WriteAttributeString("xfId", "0");
|
||||
xw.WriteEndElement(); // cellStyle
|
||||
xw.WriteEndElement(); // cellStyles
|
||||
xw.WriteEndElement(); // <cellStyle>
|
||||
xw.WriteEndElement(); // <cellStyles>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user