C# 将文件(pdf、word 等)作为附加文件添加到 onenote 页面

问题描述 投票:0回答:2

我正在尝试在我的 .net 6.0 c# 应用程序中制作一种 outlook“发送到 onenote”插件(作为拖放)。据我所知,整个电子邮件正文(从读取 outlook 收件箱/发件箱的列表视图中拖出)作为新页面推送到 onenote(listviewArchive 包含带有 .one 文件的文件夹)。唯一的问题是我似乎无法弄清楚如何将附件(不是内联,而是文件作为 mailitem 中的附件)添加到 onennote 页面,就像 outlook“发送到 onennote”一样。enter image description here 和我的enter image description here。我用来将电子邮件推送到 onenote 的代码是

using Onenote = Microsoft.Office.Interop.OneNote;

private async void listViewArchive_DragDrop(object sender, DragEventArgs e)
        {
            Point clientPoint = listViewArchive.PointToClient(new Point(e.X, e.Y));
            ListViewItem targetItem = listViewArchive.GetItemAt(clientPoint.X, clientPoint.Y);

            Onenote.Application onenoteApp = new Onenote.Application();

            if (targetItem != null && e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection)))
            {
                ViewReadOnly = false;

                string targetPath = (string)targetItem.Tag;
                string folderName = draggedFrom ? "in.one" : "out.one";

                targetPath = Path.Combine(targetPath, folderName);

                if (!File.Exists(targetPath))
                {
                    MessageBox.Show("No section file found, Mailwill not be added as a page", "File not found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                    Marshal.ReleaseComObject(onenoteApp);       
                    onenoteApp= null;
                    return;
                }

                ListView.SelectedListViewItemCollection selectedItems = (ListView.SelectedListViewItemCollection)e.Data.GetData(typeof(ListView.SelectedListViewItemCollection));

                foreach (ListViewItem item in selectedItems)
                {

                    if (item.Tag is Outlook.MailItem mailItem)
                    {

                        string m_xmlNewOutlineContent =
                        "<one:Meta name=\"{2}\" content=\"{1}\"/>" +
                        "<one:OEChildren><one:HTMLBlock><one:Data><![CDATA[{0}]]></one:Data></one:HTMLBlock></one:OEChildren>";

                        string m_xmlNewOutline =
                        "<?xml version=\"1.0\"?>" +
                        "<one:Page xmlns:one=\"{2}\" ID=\"{1}\">" +
                        "<one:Outline>{0}</one:Outline></one:Page>";

                        string m_outlineIDMetaName = "Outlook Email To OneNote AddIn ID";

                        string m_xmlns = "http://schemas.microsoft.com/office/onenote/2013/onenote";

                        await Task.Run(() =>
                        {

                            string subject = mailItem.Subject;
                            string from = mailItem.SenderName;
                            string to = mailItem.To;
                            string cc = mailItem.CC;
                            DateTime sentTime = mailItem.SentOn;
                            string attachments = "";

                            List<string> attachmentPaths = new List<string>();
                            foreach (Outlook.Attachment attachment in mailItem.Attachments)
                            {
                                bool isInline = false;
                                try
                                {
                                    isInline = (bool)attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7FFE000B");
                                }
                                catch (Exception)
                                {
                                    // still to add....
                                }

                                if (!isInline)
                                {
                                    string attachmentPath = Path.Combine(Path.GetTempPath(), attachment.FileName);
                                    attachment.SaveAsFile(attachmentPath);
                                    attachmentPaths.Add(attachmentPath);
                                    attachments += attachment.FileName + ";";
                                }
                            }

                            string insertedFiles = string.Empty;
                            foreach (string attachmentPath in attachmentPaths)
                            {
                             //code to add the files to the table in string emailBody, no idea how....
                            }
                            
                            string emailBody = 
                            "<table border=\"1\" cellpadding=\"5\"><tr><th>Subject</th><th>From</th><th>To</th><th>CC</th><th>Sent Time</th><th>Attachments</th></tr>" +
                            $"<tr><td>{subject}</td><td>{from}</td><td>{to}</td><td>{cc}</td><td>{sentTime}</td><td>{insertedFiles}</td></tr></table>" +
                            mailItem.HTMLBody;

                            // Create new OneNote page and insert email content
                            string xmlHierarchy;
                            onenoteApp.GetHierarchy("", HierarchyScope.hsSections, out xmlHierarchy);

                            string targetID = string.Empty;
                            onenoteApp.OpenHierarchy(targetPath, string.Empty, out targetID);

                            onenoteApp.CreateNewPage(targetID, out string pageID, NewPageStyle.npsBlankPageWithTitle);

                            int outlineID = new Random().Next();

                            string outlineContent = string.Format(m_xmlNewOutlineContent, emailBody, outlineID, m_outlineIDMetaName);
                            string xml = string.Format(m_xmlNewOutline, outlineContent, pageID, m_xmlns);
                            // Get the title and set it to our page name
                            onenoteApp.GetPageContent(pageID, out xml, PageInfo.piAll);
                            XNamespace ns = null;
                            var doc = XDocument.Parse(xml);
                            ns = doc.Root.Name.Namespace;
                            var title = doc.Descendants(ns + "T").First();
                            title.Value = subject;

                            // Update the page to add pagetitle/pagename
                            onenoteApp.UpdatePageContent(doc.ToString());

                            // Update the page again to add the actual body of the mailitem
                            onenoteApp.UpdatePageContent(xml, DateTime.MinValue);
                        });      
                    }
                }
            }

            Marshal.ReleaseComObject(onenoteApp);       
            onenoteApp= null;
        }

它处理内联图像并不总是正确的。我花了很多互联网搜索和复制/粘贴才能找到这个点但是...... 如果有人可以添加代码来处理附件并查看邮件正文中的内联图像,那就太好了!我没有足够的知识来弄清楚这个......

做了很多但没有保留这个。迷路了。在 stackoverflow 中搜索了很多但找不到任何关于这个的东西......


编辑/更新1:

problem 2) Attach files 尚未解决。有帮助吗?

问题 1“内联图像”看起来已解决。我在“await Task.Run(())”中移动了一些东西。现在内联图像被添加到 onenote 正文中。我将 foreach(mailItem.Attachments 中的 Outlook.Attachment 附件)移动到“string emailBody”下方并添加了其他if (isInline) 代码块。foreach 循环现在通过转换和替换以正确的方式使用内联图像更新“字符串 emailBody”。电子邮件的内联图像现在显示在 onenote 页面上

    await Task.Run(() =>
                        {

                            string subject = mailItem.Subject;
                            string from = mailItem.SenderName;
                            string to = mailItem.To;
                            string cc = mailItem.CC;
                            DateTime sentTime = mailItem.SentOn;
                            string attachments = "";

                            string insertedFiles = string.Empty;
                            
                            string emailBody = 
                            "<table border=\"1\" cellpadding=\"5\"><tr><th>Subject</th><th>From</th><th>To</th><th>CC</th><th>Sent Time</th><th>Attachments</th></tr>" +
                            $"<tr><td>{subject}</td><td>{from}</td><td>{to}</td><td>{cc}</td><td>{sentTime}</td><td>{insertedFiles}</td></tr></table>" +
                            mailItem.HTMLBody;
                            
                            List<string> attachmentPaths = new List<string>();
                            foreach (Outlook.Attachment attachment in mailItem.Attachments)
                            {

                                bool isInline = false;
                                try
                                {

                                    isInline = (bool)attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7FFE000B");
                                }
                                catch (Exception)
                                {

                                }

                                if (!isInline) 
                                //saving them mfirst on temp location is just to see if i am able to get the files
                                {
                                    string attachmentPath = Path.Combine(Path.GetTempPath(), attachment.FileName);
                                    attachment.SaveAsFile(attachmentPath);
                                    attachmentPaths.Add(attachmentPath);
                                    attachments += attachment.FileName + ";";
                                }
                                else if (isInline)
                                {
                                    byte[] attachmentData = (byte[])attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37010102");
                                    // Convert the binary data to a base64 string
                                    string base64String = Convert.ToBase64String(attachmentData);

                                    // Replace the inline image tag with the base64 encoded string
                                    string cid = attachment.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E") as string;
                                    emailBody = emailBody.Replace($"cid:{cid}", $"data:image/png;base64,{base64String}");
                                }
                            }

                            foreach (string attachmentPath in attachmentPaths)
                            {
                             //still needs solving. the save files need to be added to the onenote page as attached file
                             //but it seems redonned to first save the email attached file and the grapping them form temp location. 
                             //so be able to get them form mail directly

 
                            }
                            // Create new OneNote page and insert email content
                            string xmlHierarchy;
                            onenoteApp.GetHierarchy("", HierarchyScope.hsSections, out xmlHierarchy);

                            string targetID = string.Empty;
                            onenoteApp.OpenHierarchy(targetPath, string.Empty, out targetID);

                            onenoteApp.CreateNewPage(targetID, out string pageID, NewPageStyle.npsBlankPageWithTitle);

                            int outlineID = new Random().Next();

                            string outlineContent = string.Format(m_xmlNewOutlineContent, emailBody, outlineID, m_outlineIDMetaName);
                            string xml = string.Format(m_xmlNewOutline, outlineContent, pageID, m_xmlns);

                            // Get the title and set it to our page name
                            onenoteApp.GetPageContent(pageID, out xml, PageInfo.piAll);
                            XNamespace ns = null;
                            var doc = XDocument.Parse(xml);
                            ns = doc.Root.Name.Namespace;
                            var title = doc.Descendants(ns + "T").First();
                            
                            title.Value = subject;

                            // Update the page to add pagetitle/pagename
                            onenoteApp.UpdatePageContent(doc.ToString());

                            outlineContent = string.Format(m_xmlNewOutlineContent,emailBody, outlineID, m_outlineIDMetaName);
                            xml = string.Format(m_xmlNewOutline, outlineContent, pageID, m_xmlns);

                            // Update the page again to add the actual body of the mailitem
                            onenoteApp.UpdatePageContent(xml, DateTime.MinValue);
                        });
outlook drag-and-drop html-email email-attachments onenote
2个回答
0
投票

听起来您只需要为附加的文件附加图像,并在需要的地方(在表格单元格中)显示在消息正文中。以下代码显示了如何附加图像,然后在邮件正文中设置对它的引用:

Attachment attachment = newMail.Attachments.Add(@"E:\Pictures\image001.jpg", OlAttachmentType.olEmbeddeditem, null, "Some image display name");
string imageCid = "image@123";
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageCid);
newMail.HTMLBody = String.Format("<body><img src=\"cid:{0}\"></body>", imageCid);

您基本上需要在附件上设置

PR_ATTACH_CONTENT_ID
属性,然后在正文中引用它。此外,如果您想从视图中隐藏附件,您还可以考虑设置
PT_ATTACH_HIDDEN
属性(DASL 名称为
http://schemas.microsoft.com/mapi/proptag/0x7FFE000B
)。

Outlook不支持base64图片,需要处理附加项。所以下面这段代码没有任何意义:

emailBody = emailBody.Replace($"cid:{cid}", $"data:image/png;base64,{base64String}");

使用

<a>
元素在邮件正文中显示附加项目,其中
src
属性设置为CID值(见上文)。


0
投票

编辑/更新2:

我也解决了第二个问题,实际上并不是很复杂,见下文。这会将 outlook 文件附件作为文件附件添加到 onenote 页面。仍然需要重写整个 Dragdrop 方法才能......更好!

  1. 一般代码编写:健壮性、最佳实践、异常/错误处理
  2. 文件附件放在页面本身的位置
  3. 更好地处理邮件中的多个文件附件。目前的方式确实适用于多个附件。
  4. 可选:附件直接从邮件项目中提取,不保存到临时位置,否则清理临时位置。
 if (!isInline)
 {
    string attachmentPath = Path.Combine(Path.GetTempPath(), attachment.FileName);
    attachment.SaveAsFile(attachmentPath);

    //enclose the file in the correct onenote node
    attachments += string.Format("<one:InsertedFile pathSource=\"{0}\" preferredName=\"{1}\" />", attachmentPath, attachment.FileName);

    //update string incase this if statement is invoked
    m_xmlNewOutline =
    "<?xml version=\"1.0\"?>" +
    "<one:Page xmlns:one=\"{2}\" ID=\"{1}\">" +
    $"{attachments}"+
    "<one:Outline>{0}" +
    "</one:Outline></one:Page>";
    //still need to look at handling multiple fileattachments... 
 }

但至少上面的代码可以将 outlook 文件附件附加到 onenote 页面。整个 DragDrop 方法还包括我制作的自定义进度条的实例,用于指示某些内容正在复制到/保存到 onenote,并且 mailitem 本身获得一个自定义属性,指示 mailitem 已存档到 onenote。这在 listviewInbox/Outbox 中启用了一个复选框,并使这些列表视图中的项目“变灰”...

© www.soinside.com 2019 - 2024. All rights reserved.