Как я уже упоминал в комментариях, я думаю, что написание сценария ac #, который считывает данные из ячеек Excel и группирует их в список или DataTable, а затем выполняет групповую вставку один раз, будет более производительным [1117 ]
Сначала необходимо импортировать сборку Excel Interop:
using Microsoft.Office.Interop.Excel;
using System.Data.SqlClient;
Теперь вы должны определить следующую функцию, которая преобразует алфавит столбца Excel в индекс:
private int ParseColHeaderToIndex(string colAdress)
{
int[] digits = new int[colAdress.Length];
for (int i = 0; i < colAdress.Length; i++)
{
digits[i] = Convert.ToInt32(colAdress[i]) - 64;
}
int mul = 1;
int res = 0;
for (int pos = digits.Length - 1; pos >= 0; pos--)
{
res += digits[pos] * mul;
mul *= 26;
}
return res;
}
Следующая функция предназначена для выполнения операции массовой вставки в SQL [ 1120]
public void InsertToSQLUsingSQLBulk(System.Data.DataTable dt, string connectionstring, string Tablename)
{
try
{
using (var bulkCopy = new SqlBulkCopy(connectionstring, SqlBulkCopyOptions.KeepIdentity))
{
foreach (DataColumn col in dt.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = Tablename;
bulkCopy.WriteToServer(dt);
}
}
catch (Exception ex)
{
throw ex;
}
}
Следующая функция принимает путь Excel и диапазоны DataTable в качестве параметра и возвращает DataTable со структурой назначения (Id, AttributeKey, AttributeValue )
public System.Data.DataTable ReadFromExcel(System.Data.DataTable dtRanges,string strPath)
{
string num = "0123456789";
//Declare result datatable
System.Data.DataTable destination = new System.Data.DataTable();
destination.Columns.Add("Id");
destination.Columns.Add("AttributeKey");
destination.Columns.Add("AttributeValue");
//Decalre Interop Objects
Microsoft.Office.Interop.Excel.Application m_XlApp;
m_XlApp = new Microsoft.Office.Interop.Excel.Application();
m_XlApp.Visible = false;
m_XlApp.DisplayAlerts = false;
Workbook xlWbs = null;
xlWbs = m_XlApp.Workbooks.Open(strPath, Type.Missing, Type.Missing,
Type.Missing, "'", Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
xlWbs.DoNotPromptForConvert = true;
xlWbs.CheckCompatibility = false;
xlWbs.Application.DisplayAlerts = false;
//Loop over worksheets
foreach (Worksheet xlWks in xlWbs.Worksheets) {
string Name = xlWks.Name;
//Assing rows relevant to the current sheet
foreach (DataRow drRow in dtRanges.AsEnumerable().Where(x => x["Sheet_Name"].ToString() == Name))
{
string sheet = drRow["Sheet_Name"].ToString();
string range = drRow["Location_Value"].ToString();
string field = drRow["Field_Name"].ToString();
string id = drRow["Id"].ToString();
string rangeAlpha = range.Split(':')[0];
int rowidx = 0;
int colidx = 0;
foreach (char chr in num) {
rangeAlpha = rangeAlpha.Replace(chr, '\0');
}
rowidx = Int32.Parse(range.Split(':')[0].Replace(rangeAlpha, ""));
colidx = ParseColHeaderToIndex(rangeAlpha);
DataRow dr = destination.NewRow();
if (xlWks.Cells[rowidx, colidx] != null && (xlWks.Cells[rowidx, colidx] as Range).Value2 != null)
{
dr["AttributeValue"] = (string)(xlWks.Cells[rowidx, colidx] as Range).Value2;
}
else
{
dr["AttributeValue"] = "";
}
dr["AttributeKey"] = drRow["Field_Name"].ToString();
dr["Id"] = drRow["Id"].ToString();
destination.Rows.Add(dr);
}
}
xlWbs.Close(false, Type.Missing, Type.Missing);
m_XlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWbs);
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_XlApp);
return destination;
}
public void Main(){
//Initialize ranges table
System.Data.DataTable ranges = new System.Data.DataTable();
ranges.Columns.Add("Id");
ranges.Columns.Add("Field_Name");
ranges.Columns.Add("Location_Value");
ranges.Columns.Add("Sheet_Name");
//Add rows or read them from database using SQLDataAdapter
//note that the destination table must exists in the database with identical columns of datatable
System.Data.DataTable destination = ReadFromExcel(ranges, "C:\\1.xlsx", "dbo.destination");
InsertToSQLUsingSQLBulk(destination, "Pass SQL Server destination connection string here");
}
Вы можете улучшить Производительность метода заключается в размещении всего содержимого рабочего листа в двухмерном массиве, а затем в цикле по массиву, а не в цикле внутри рабочего листа Excel.
Excel.Range targetCells = xlWks.UsedRange;
object[,] allValues = (object[,])targetCells.Cells.Value;
...
if (targetCells.Cells[rowidx, colidx] != null)
{
dr["AttributeValue"] = (string)(targetCells.Cells[rowidx, colidx] as Range).Value2;
}
else
{
dr["AttributeValue"] = "";
}
Справочник
Я вполне уверен, это будет невозможным, не используя Outlook и профиль MAPI. Если бы можно льстить почтовому администратору во включение IMAP на Exchange Server, это сделало бы жизнь намного легче.
Вам нужно будет найти способ запустить процесс от имени этого конкретного пользователя.
Я думаю, что pywin32.CreateProcessAsUser - это начало пути, по которому вам нужно идти. Последнее редактирование Дескриптор вошедшего в систему пользователя получен с использованием метода win32security.LogonUser
Я знаю, что это старая тема, но...
Если вы используете Exchange 2007 или новее, или Office365, взгляните на Exchange Web Services. Это довольно полный SOAP-интерфейс для Exchange, и вы можете делать практически все, что умеет Outlook, включая делегирование или имперсональный доступ к другим учетным записям пользователей.
http://msdn.microsoft.com/en-us/library/bb204119.aspx
ОБНОВЛЕНИЕ: Я выпустил Python EWS клиент на PyPI, который поддерживает автообнаружение, календари, входящие, задачи, контакты и многое другое:
from exchangelib import DELEGATE, Account, Credentials
credentials = Credentials(
username='MYWINDOMAIN\\myusername', # Or myusername@example.com for O365
password='topsecret'
)
account = Account(
primary_smtp_address='john@example.com',
credentials=credentials,
autodiscover=True,
access_type=DELEGATE
)
# Print first 100 inbox messages in reverse order
for item in account.inbox.all().order_by('-datetime_received')[:100]:
print(item.subject, item.body, item.attachments)