mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 01:25:41 -05:00
Save As Excel (#279)
* Fix dispose pattern usage in SaveAsWriterBase * Add SaveAsExcel feature This adds the save as excel function to the backend. To reduce large dependency and run on dotnet core now, this implementation use a raw excel writer (the SaveAsExcelFileStreamWriterHelper.cs) instrad of popular excel library, such as EPPlus or OpenXmlSdk. * Fix can not open the generated excel file in google sheet For the file name inside excel, google uses a case sensitive path while Excel doesn't. This change fix the case, so that the file name matches the one in x1/_rels/workbook.xml.rels * Fix datetime doesn't recognized by google sheet Google doesn't support cell type t="d" with ISO 8601 date. (From stackoverflow thread and testing), thus use the old way of excel datetime, which uses double to present datetime * update to use xmlwriter * Add basic unit tests for SaveAsExcelFileStreamWriterHelper * refactor: simplify the public interface of the SaveAsExcelFileStreamWriterHelper * update private fields names based on the name convention * Add comments to classes of SaveAsExcel feature * clean up SaveAsExcelFileStreamWriterHelper - change SaveAsExcelFileStreamWriterHelper from public to internal - remove the PenddingRowEndTag function from referenceManager - change the SaveAsExcelFileStreamWriterHelper(stream) to default leaveOpen to false to match the normal behavior - change the rowreference to use XmlConvert to convert int to string - rename writeSetting to writerSetting and add private * fix CI test error for SaveAsExcel * remove ExporterException in SaveAsExcel * fix lefe over CSV to Excel in the comments * refactor to be consistent with JsonWriter and remove the comment * remove commented out test The test is too slow to run * fix typo in comment * refactor SaveAsExcel to the coding standard * refactor rewrite the WriteStyle with XmlWriter * Add licence header * reverse mistakenly checked-in changes * fix: left-over CSV in commets * remove duplicate check The check was done in the IncreaseColumnReference, but that check is too late in case of too many columns. All the addCell do the check at the begining now * fix TimeSpan more than 24 hours * fix AddRowMustBeCalledBeforeAddCellException test This is due to remove duplicate call to AssureColumnReference in WriteAndIncreaseColumnReference * fix: TimeSpan will write twice * style: change retun in the switch to break * Add bool format * remove todo in comment This provides extra safeguard in the cost of one memory access when null.
This commit is contained in:
committed by
Benjamin Russell
parent
8d017368f9
commit
8d47d5c7b3
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// Writer for writing rows of results to a Excel file
|
||||
/// </summary>
|
||||
public class SaveAsExcelFileStreamWriter : SaveAsStreamWriter
|
||||
{
|
||||
|
||||
#region Member Variables
|
||||
|
||||
private readonly SaveResultsAsExcelRequestParams saveParams;
|
||||
private bool headerWritten;
|
||||
private SaveAsExcelFileStreamWriterHelper helper;
|
||||
private SaveAsExcelFileStreamWriterHelper.ExcelSheet sheet;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor, stores the Excel specific request params locally, chains into the base
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="stream">FileStream to access the Excel file output</param>
|
||||
/// <param name="requestParams">Excel save as request parameters</param>
|
||||
public SaveAsExcelFileStreamWriter(Stream stream, SaveResultsAsExcelRequestParams requestParams)
|
||||
: base(stream, requestParams)
|
||||
{
|
||||
saveParams = requestParams;
|
||||
helper = new SaveAsExcelFileStreamWriterHelper(stream);
|
||||
sheet = helper.AddSheet();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a row of data as a Excel row. If this is the first row and the user has requested
|
||||
/// it, the headers for the column will be emitted as well.
|
||||
/// </summary>
|
||||
/// <param name="row">The data of the row to output to the file</param>
|
||||
/// <param name="columns">
|
||||
/// The entire list of columns for the result set. They will be filtered down as per the
|
||||
/// request params.
|
||||
/// </param>
|
||||
public override void WriteRow(IList<DbCellValue> row, IList<DbColumnWrapper> columns)
|
||||
{
|
||||
int columnStart = ColumnStartIndex ?? 0;
|
||||
int columnEnd = (ColumnEndIndex != null) ? ColumnEndIndex.Value + 1 : columns.Count;
|
||||
|
||||
// Write out the header if we haven't already and the user chose to have it
|
||||
if (saveParams.IncludeHeaders && !headerWritten)
|
||||
{
|
||||
sheet.AddRow();
|
||||
for (int i = columnStart; i < columnEnd; i++)
|
||||
{
|
||||
sheet.AddCell(columns[i].ColumnName);
|
||||
}
|
||||
headerWritten = true;
|
||||
}
|
||||
|
||||
sheet.AddRow();
|
||||
for (int i = columnStart; i < columnEnd; i++)
|
||||
{
|
||||
sheet.AddCell(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private bool disposed;
|
||||
override protected void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
sheet.Dispose();
|
||||
helper.Dispose();
|
||||
|
||||
disposed = true;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user