1

我每周都会收到一封带有 excel 文件的电子邮件。我知道可能有更好的方法来实现我的目标,但是是否有可能在 SSIS 中有一个脚本任务可以打开电子邮件,查找特定文件名作为附件,然后将该文件复制到另一个位置?

这是场景。这个 excel 文件对于我的团队在 SQL 数据库中很重要,并且 excel 源的提供者只愿意每周通过电子邮件将这个 excel 文件发送给我们一次。然后我检查我的电子邮件,将文件复制到一个位置,然后 SSIS 数据流任务可以将其提取并插入到 SQL 表中。我想自动化这个。因此,如果我原来的方法不可行,那还能如何实现自动化呢?除了使用共享网络位置。假设 excel 文件只能来自电子邮件。使用 Outlook/Office 365、SSIS、SSMS,我有 DBO 访问权限,并且可以使用 c#。

我承认我对电子邮件一无所知。如果有一个电子邮件客户端可以实际执行的过程来完成此操作,那么我会全神贯注!

编辑:我也可以访问网络驱动器,因为我意识到保存到我的本地机器可能是不可能的。

4

1 回答 1

2

简单的答案是的,这是可能的。

我写了一个控制台程序来处理 Office365 上的电子邮件,我也与 SQL 接口,所以它绝对可以完成。它不一定是世界上最简单的事情,但也不是太难。

您可以使用 Exchange Web 服务 (EWS) 托管 API

关于说明可能的文章和 API 文档 https://msdn.microsoft.com/en-us/library/office/dd877012(v=exchg.150).aspx

您可以在其中找到 API 的 Github 位置(注意此链接直接来自 Microsoft 的站点) https://github.com/officedev/ews-managed-api

有关如何引用包含上述第二个链接的程序集的链接: https ://msdn.microsoft.com/en-us/library/office/dn528373(v=exchg.150).aspx

创建并连接到服务

string emailAddress = 'YourEmail@Domain.com';
ExchangeService exService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exService.Credentials = new WebCredentials(emailAddress,"password");

您可以自动发现,或者如果您知道 URL,只需将其设置为这些行中的 1 行

exService.AutodiscoverUrl(_emailAddress, delegate { return true; });
exService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

找到您的收件箱和文件夹以在处理后将文件移动到:

FolderView folderView = new FolderView(1);
folderView.PropertySet = new PropertySet(BasePropertySet.IdOnly);
folderView.PropertySet.Add(FolderSchema.DisplayName);
folderView.Traversal = FolderTraversal.Deep;
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "ProcessedFolderName");
Folder Inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
FindFoldersResults folderResults = Inbox.FindFolders(searchFilter, folderView);
FolderId processedFolderId = folderResults.Folders[0].Id;

查找符合您条件的消息:

List<SearchFilter> searchFilterCollection = new List<SearchFilter();
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,"Words in Subject"));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(ItemSchema.HasAttachments,true));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.From,new EmailAddress("From@SendersDomain.com")));
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,searchFilterCollection);

ItemView view = new ItemView(50, 0, OffsetBasePoint.Beginning);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived, ItemSchema.Attachments);
view.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox,searchFilter,view);

处理结果并在完成后保存附件将邮件移动到另一个文件夹,这样您就不会继续导入同一个文件夹。

foreach (Item i in findResults.Items)
{
    foreach(FileAttachment attachment in i.Attachments)
    {
        attachment.Load(@"\\FilePathDirectory\" + attachment.FileName);
    }

    i.Move(processedFolderId);
}

如果没有结果,您可以通过测试来扩展解决方案,向自己发送错误消息或抛出错误以使 SSIS 拾取并失败作业。如果您要处理多条消息,您可能会多次覆盖文件,因此您可以考虑在文件名中添加一些独特的东西,而不是只使用相同的,但这也会在 SSIS 中带来其他挑战。

无论如何,这是一个开始,希望它有所帮助。

于 2016-09-21T17:04:26.900 回答