Решение, основанное на статье tuncalik (спасибо за идею), но в случае больших таблиц работает намного быстрее (и немного менее понятно).
public static class My_DataTable_Extensions
{
/// <summary>
/// Export DataTable to Excel file
/// </summary>
/// <param name="DataTable">Source DataTable</param>
/// <param name="ExcelFilePath">Path to result file name</param>
public static void ExportToExcel(this System.Data.DataTable DataTable, string ExcelFilePath = null)
{
try
{
int ColumnsCount;
if (DataTable == null || (ColumnsCount = DataTable.Columns.Count) == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbooks.Add();
// single worksheet
Microsoft.Office.Interop.Excel._Worksheet Worksheet = Excel.ActiveSheet;
object[] Header = new object[ColumnsCount];
// column headings
for (int i = 0; i < ColumnsCount; i++)
Header[i] = DataTable.Columns[i].ColumnName;
Microsoft.Office.Interop.Excel.Range HeaderRange = Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, ColumnsCount]));
HeaderRange.Value = Header;
HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
HeaderRange.Font.Bold = true;
// DataCells
int RowsCount = DataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount];
for (int j = 0; j < RowsCount; j++)
for (int i = 0; i < ColumnsCount; i++)
Cells[j, i] = DataTable.Rows[j][i];
Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[2, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[RowsCount + 1, ColumnsCount])).Value = Cells;
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
try
{
Worksheet.SaveAs(ExcelFilePath);
Excel.Quit();
System.Windows.MessageBox.Show("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
}
else // no filepath is given
{
Excel.Visible = true;
}
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
}
Я просто запустил быстрый тест и заметил следующее, которое может помочь Вам:
Этот сценарий не приостановится, если выполнено от консоли команды, но будет, если дважды щелкнули в Проводнике:
@echo off
setlocal enableextensions
set SCRIPT=%0
set DQUOTE="
@echo do something...
@echo %SCRIPT:~0,1% | findstr /l %DQUOTE% > NUL
if %ERRORLEVEL% EQU 0 set PAUSE_ON_CLOSE=1
:EXIT
if defined PAUSE_ON_CLOSE pause
РЕДАКТИРОВАНИЕ: было также некоторое странное поведение при выполнении из Проводника, который я не могу объяснить. Первоначально, а не
@echo %SCRIPT:~0,1% | findstr /l %DQUOTE% > NUL
if %ERRORLEVEL% EQU 0 set PAUSE_ON_CLOSE=1
я пытался использовать просто if
:
if %SCRIPT:0,1% == ^" set PAUSE_ON_CLOSE=1
Это работало бы при выполнении от открытой командной строки, но, когда выполнено из Проводника она будет жаловаться, что if
оператор не был корректен.
Не пропускайте решение наличия двух пакетных файлов:
abatfile.bat и abatfile-with-pause.bat
второе просто вызов первого и добавление паузы
Я использую параметр "автоматический режим", когда я выполняю свои пакетные файлы из сценариев.
set automode=%7
(Здесь автоматический режим является седьмым данным параметром.)
Некоторый код следует и когда файл должен приостановиться, я делаю это:
if @%automode%==@ pause
Подобный второму пакетному файлу Вы могли также приостановиться, если определенный параметр не дан (названный через нажатие).
Это означало бы только один пакетный файл, но имеющий необходимость определить -nopause
параметр или что-то как этот при вызове от консоли.
сумасшедшая идея: используйте список задач и синтаксический анализ, это - результаты. Я имею, записал в тестовом пакетном файле:
список задач> test.out
и когда я дважды щелкнул по нему, был дополнительным процессом "cmd.exe" непосредственно перед процессом списка задач, который не был там, когда сценарий был выполнен из командной строки (но обратите внимание, что это не могло бы быть достаточно, если кто-то открывает оболочку командной строки, и затем дважды щелкните по пакетному файлу)
Просто добавьте паузу независимо от того, как она была открыта? Если это было открыто от командной строки никакой вред, причиненный кроме безопасной паузы. (Не решение, но просто думающий, была ли пауза настолько вредной / раздражающий)