Save complete email, body and header, as PDF - outlook

I want to save complete mail as PDF.
I found code below in stackoverflow 1. It saves the mailitem body and not the header (such as sender, recipient, subject).
I tried to manipulate the Word.Document to add the header info manually (in the code below I just use minimal changes for testing purposes) but it seems to be readonly. I also thought of "Print as PDF" using the Outlook print functionality, but found no way to get it triggered from my Outlook VSTO solution.
using Word = Microsoft.Office.Interop.Word;
private void SaveMailAsPDF(Outlook.MailItem _mailitem)
{
//source: https://stackoverflow.com/questions/26421252/save-outlook-mailitem-body-as-pdf
Outlook.MailItem mi = _mailitem;
mi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
string datetimeReceived = mi.ReceivedTime.ToString("yyyyMMdd-Hmmss");
string fullPath = #"C:\Users\al\Documents\OutlookMailsTest\" + datetimeReceived + "Test.pdf";
Word.Document doc = mi.GetInspector.WordEditor;
//doc.Paragraphs.Add();
//doc.Paragraphs.Add();
//Word.Range rng = doc.Range(0, 0);
//rng.Text = "New Text";
doc.SaveAs2(fullPath, FileFormat: Word.WdSaveFormat.wdFormatPDF);
}

Try to save in the MHTML format (it preserves the embedded pictures and includes the headers) using MailItem.SaveAs, then open the MHTML file using Word object model and save it as a PDF file.

The Outlook object model doesn't provide any print as pdf methods. The MailItem.PrintOut method prints the Outlook item using all default settings.The PrintOut method is the only Outlook method that can be used for printing.
You can use the Word object model for saving the message body in the format you need. For example, you may save the document which represents the message body using the open XML document (*.docx) and then open it for editing using Open XML SDK for adding message headers (if required). See Welcome to the Open XML SDK 2.5 for Office for more information.
You are free to use third-party components to save the document with required customizations using the PDF file format.

Related

Setting plain text email's body format to HTML using Microsoft Outlook Interop Library corrupts the email content

This seems to start happening out of no where since May this year to the desktop version of Outlook, almost looks like a bug from some recent update that Microsoft is rolling out.
So I have the following simple code to reproduce this problem:
var app = new Application();
var session = app.Session;
var mail = (MailItem)session.GetItemFromID("0000");
// mail.BodyFormat is olBodyFormat.Plain
// setting it to olFormatHTML corrupts the email body
mail.BodyFormat = OlBodyFormat.olFormatHTML;
// after setting the body format to olFormatHTML, the body format remains olBodyFormat.Plain
The email body text after trying to set the body format to HTML changes to incorrect Unicode characters.
The following code achieves the same result:
var app = new Application();
var session = app.Session;
var mail = (MailItem)session.GetItemFromID("00000");
mail.HTMLBody = mail.Body;
If the plain text body was "asdf" and the email body encoding is Western European (Windows), i.e. InternetCodepage = 20127, it converts the text to "獡晤".
At first I thought this could be a page encoding problem so I tried the following code:
var app = new Application();
var session = app.Session;
var mail = (MailItem)session.GetItemFromID("00000");
mail.InternetCodepage = 65001; // sets the email encoding to UTF-8
mail.HTMLBody = mail.Body;
Yet the same thing still happens.
It seems that if I use Redemption to do this, the problem doesn't happen, but there are side effects to do this with Redemption.
After Redemption updates the email body, the Outlook inspector or the email window doesn't change the body format, as if Outlook still caches the old value. If you reply this email now, the sent email will have an empty body.
Does any one know if I'm doing anything wrong here or this is really a Microsoft Outlook bug?
Looks like this is a product issue. I'd recommend opening a support case with MS then.
As a possible workaround you can use the Word editor for setting up the message body correctly. The Inspector.WordEditor property returns the Microsoft Word Document Object Model of the message being displayed.

Include signature in VBA created email Outlook 2013

Here's what I've got. It works to create a message with HTML format, but I want it to include my signature and I'm not sure how to do that. I looked at some other answers and their solutions don't seem to work for Outlook 2013.
Sub CreateHTMLMail()
'Creates a new email item and modifies its properties.
Dim objMail As MailItem
'Create mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "test"
.Display
End With
End Sub
There is no signature-specific property in the Outlook object model. You can detect the existing signature (if any) by reading the existing set of signatures (if any) in the following folders, so if you create a signature in Outlook it will save three files (HTM, TXT and RTF):
Vista and Windows 7/8/8.1/10:
C:\Users\<UserName>\AppData\Roaming\Microsoft\Signatures
Windows XP :
C:\Documents and Settings\<UserName>\Application Data\Microsoft\Signatures
Application Data and AppData are hidden folders, change the view in Windows explorer so it shows hidden files and folders if you want to see the files.
Outlook adds the signature to the new unmodified messages (you should not modify the body prior to that) when you call MailItem.Display (which causes the message to be displayed on the screen) or when you access the MailItem.GetInspector property - you do not have to do anything with the returned Inspector object, but Outlook will populate the message body with the signature.
Once the signature is added, read the HTMLBody property and merge it with the HTML string that you are trying to set. Note that you cannot simply concatenate two HTML strings - the strings need to be merged. E.g. if you want to insert your string at the top of the HTML body, look for the <body substring, then find the next occurrence of > (this takes care of the <body> element with attributes), then insert your HTML string after that >.

Content-Disposition inline filename issue with IE

I am displaying a pdf in browser with inline from API using an aspx page.
While saving the pdf using Chrome/Firefox, takes the filename from header("Content-Disposition", "inline;filename=xyz.pdf")
But while saving the pdf using IE it does not reads the filename from header("Content-Disposition", "inline;filename=xyz.pdf"). instead it takes the aspx name.
Technical details
I have an xyz.aspx page.
The xyz.aspx page will invoke an API for a document.
Then the downloaded document from API will transferred to browser with inline to display the pdf document.
Am setting the response header as below and writing the file bytes.
HttpContext.Current.Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "inline;filename=\"" + Name + "\"");
HttpContext.Current.Response.ContentType = "application/pdf";
Issue:
While saving the opened pdf in IE it takes xyz.aspx instead of the name from header.
Requirement:
While saving the pdf using IE, it need to save with the name of pdf.
I googled so much, as every one tells its IE behavior. I hope some one knows a solution.
Note: I have to display the pdf in browser and then save. Not to download using "attachment"
It is true some versions of IE can't handle ("Content-Disposition", "inline;filename=...")
This is because filename=... was originally intended for the attachment disposition. Not all browser-based PDF viewers can handle it.
The only solution I see is to allow access via a different url.
Suppose you have a route to the pdf like: /pdf/view. If you change it to /pdf/view/filename and you configure your application to handle this route in the same way as /pdf/view your problem is solved.
You can also re-write the download url on the webserver.
Depending on your webserver you have various ways of doing this.
I have also tried with all kind of headers and methods.
In the end, my solution was
private FileResult ReturnStreamAsPdf(string fileName, Stream stream)
{
ContentDisposition cd = new ContentDisposition
{
FileName = fileName,
Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
return new FileStreamResult(stream, MediaTypeNames.Application.Pdf);
}
and the Route Attribute on the method:
[Route("api/getpdfticket/{ticketnumber}")]
public async Task<FileResult> GetPdfTicket(string ticketnumber)
And the href:
href="#($"/api/getpdfticket/{product.TicketNumber}.pdf")"
It seems like Microsloft is still inventing their own standards:
http://test.greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf
PDF Handler : content-disposition filename

How to retrive the data displayed in Message box for Coded Ui testing

Scenario: After clicking on the submit button,a message box appears with the ticket number. I want to save the ticket number to a string parameter for future purposes. Is it possible in Coded Ui?
Use the Assertion tool to select the textbox and name it "CaptureText()" (Do this to use the tool to capture the object). Once you've done this, transfer the code from the UIMap Designer File to the Coded File. Inside your Coded UIMap File you should see something like this:
public void CaptureText()
{
HtmlCustom uIItemCustom = this.Window.Foo.Bar.UIItem;
//Comment this out
//Assert.IsNull(uIItemCustom);
//Change it to
var foo = uIItemCustom.InnerText;
}
Now the 'foo' variable contains the value of the label / textbox.

How to use System.Drawing.Image in RDLC Image Control?

Is it possible to use System.Drawing.Image in an RDLC Image Control?
All I have been reading were 3 methods:
database
embeded resource
external file
Thank you thank you.
EDIT:
Following up from this .NET or C# library for CGM (Computer Graphics Metafile) format? I now got the image in System.Drawing.Image format and want to display it as part of the report (as an image) --- that's what I want to do.
Not sure if this is what you are looking for, but if you have an image in code and you want to show it in the report, create a wrapper object that has a property that returns the image as a byte array and give then an instance of this wrapper-class with the valid image to the report as a ReportDataSource.
Something like:
ReportDataSource logoDataSource = new ReportDataSource();
logoDataSource.Name = "LogoDS";
logoDataSource.Value = new List<LogoWrapper>() { yourLogoWrapper };
localReport.DataSources.Add(logoDS);
In the report you then you can the image as it were from the database
=First(Fields!LogoByteArrayProperty.Value, "LogoDS")
The wrapper looks something like:
class LogoWrapper{
...
public byte[] LogoByteArrayProperty{
get{
// Return here the image data
}
}
}
I use this quite often. It has the advantage that I don't have to add the image to the db or add it as a resource of every report. And furthermore, the app can say which image should be used.
Please note, the given image format must be known from the rdlc-engine.
The last question would be, how to convert a system.drawing.image to a byte array. I work with WPF and therefore, I dont known. But I'm sure google will respond to this question very reliable.
You Can use the 'Database' Source Option along with Parameters to Dynamically set Image Source from Byte Arrays.
Code Behind:
var param2 = new ReportParameter()
{
Name = "CompanyLogo",
Values = { Convert.ToBase64String(*ByteArrayImageObject*) }
};
ReportViewer1.LocalReport.SetParameters(param2);
rdlc File:
1- Add Text Parameters 'CompanyLogo' and 'MIMEType'
2- Set the Value Property of the Image to =System.Convert.FromBase64String(Parameters!CompanyLogo.Value)
3- Set MIME Type Property to
=Parameters!MIMEType.Value
4- Use 'Database' As Source
How can I render a PNG image (as a memory stream) onto a .NET ReportViewer report surface
i am not quite sure what do you want to do with this but in general it is not possible.Image Control is just a image holder in the RDLC files.These 3 options specify the location from where the image control takes the image which to display from- database, embeded resource or external file. If you give me more info on what do you want to achieve i can give you some kind of solution.
Best Regards,
Iordan

Resources