Thursday, November 15, 2012

How to print a PDF file inside your Windows applicaiton

I have shown you how to export report's output to PDF file using SSRS service the other day.  You now have PDF files generated by this service, but what if you want to print one of these PDF files programmatically inside your Windows applicaiton?

This can be easily done by using the acrobat reader, which is already residing in user's PC.

Here is the source code of actual procedure that I am using in a couple of my projects, and this is how it works.

  1. You call this static procedure with three input parameters
  2. The procedure creates a new process and runs the acrobat reader with the file
  3. The acrobat reader is open in a hidden mode and prints the file
  4. The process waits for a certain time before it is killed.

For the input parameter "acrobatFullPath," my suggestion is to code a small function to get a full path of user's acrobat reader in user's PC.
Otherwise, you probably can use this hardcoded value for that parameter.
C:\Program Files (x86)\Adobe\Reader 9.0\Reader\AcroRd32.exe
Also, inside my application, I gave 30 seconds to "timeBeforeClosing" parameter.

Please feel free to copy & modify.

// prints a given PDF file using user's Acrobat Reader
public static void PrintPDFUsingAcrobatReader(string acrobatFullPath, int timeBeforeClosing, string fileToBePrinted)
            // create a new process
            Process proc = new Process();
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                proc.StartInfo.Verb = "print";

                proc.StartInfo.FileName = acrobatFullPath;
                proc.StartInfo.Arguments = @"/p /h " + fileToBePrinted;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.CreateNoWindow = true;

                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                if (proc.HasExited == false)
                    proc.WaitForExit(timeBeforeClosing * 1000);

                proc.EnableRaisingEvents = true;
            catch (Exception e)
                throw e;
                proc = null;

Sunday, November 4, 2012

How to categorize your question in EileensNotes

In EileensNotes, you can label or categorize your question with proper keyword(s). In many web applications or sites, these categories or labels are also called tags.

EileensNotes also follows this trend, so you can easily categorize your question when posting a new question. (Fig. 1)

Fig. 1

Keyword(s) will be automatically hyperlinked, so using a meaningful or proper name for keyword will expose your question to other users much more easily.  After posting your own question with keywords, the posted question will just look like the question in Fig. 2.  In this question, the author used three keywords to categorize this. math, middle school, 7th grade math

Fig. 2

As I mentioned above, all of these keywords are hyperlinked.  What this means is that clicking on each category keyword gives you a list of all questions having the same keyword in categories.

In main "All Questions" and "All Advertisements" pages, EileensNotes gives you top 20 keywords that are currently used. This is also called tags cloud in other web sites, and this will let you easily navigate Q&As and advertisements by category. (Fig. 3)

Fig. 3

EileensNotes is an online Q&A site, started out of the bedroom of my daughter. It is now for all students and learners. Post/Share/Bookmark Q&As, and post your ADs.

Thursday, November 1, 2012

How to export SSRS report to PDF file format

These days, generating and running your business report has become an easy task by using Microsoft SSRS. Once you finish building your own report, you can run it from the web browser inside of your network or you can code your application to export the report to any format.  Since I kept getting this same question from friends and colleagues over and over, here I am posting the simple "How To."

1. Setting up the web reference

In my own application, I was using SSRS 2010 report server along with 2005 SSRS report execution server.

Specify your report server web reference URL
Specify your report execution server URL

2. Add the following procedure to your application

You can re-program this to accommodate your application environments.

// I am using the hashtable to pass "report parameter & value" pair
// If you have more than one report to run, call this procedure inside a loop of "reports"
public void Rpt_GenerateReport(string reportLocation, Hashtable userParamValues, string targetLocationFile, string renderingFormat)
            SSRS.ReportingService2010 rptService = new SSRS.ReportingService2010();
            SSRSExec.ReportExecutionService rptExecute = new SSRSExec.ReportExecutionService();

            // rptService.UseDefaultCredentials = true;
            rptService.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rptService.Timeout = 3000000;
            rptExecute.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rptExecute.Timeout = 3000000;

                // run for each report
                // these variables are only for temporary usage here
                bool forRendering = true;
                string historyId = null;
                string encoding;
                string mimeType;
                string extention;
                string[] streamIDs;
                SSRS.ParameterValue[] parameterValues = null;
                SSRS.DataSourceCredentials[] dataCredentials = null;
                SSRS.ItemParameter[] itemParameters = null;
                SSRSExec.ParameterValue[] execParameterValues = null;
                SSRSExec.Warning[] warnings;

                // load the report first
                ExecutionInfo execInfo = rptExecute.LoadReport(reportLocation, null);

                // the next block of codes will get a set of real parameters from a given report and
                // assign user's defined parameter value to the parameter
                itemParameters = rptService.GetItemParameters(reportLocation,
                // initialize execParameterValues for this report
                execParameterValues = new SSRSExec.ParameterValue[itemParameters.Count()];
                int paramIndex = 0;

                if (itemParameters != null)
                    // this report needs a report parameter & its value
                    // assign a value to the report parameter 
                    foreach (ItemParameter param in itemParameters)
                        SSRSExec.ParameterValue assignThis = new SSRSExec.ParameterValue();
                        assignThis.Label = param.Name;
                        assignThis.Name = param.Name;
                        assignThis.Value = userParamValues[param.Name].ToString();
                        execParameterValues[paramIndex++] = assignThis;
                    rptExecute.SetExecutionParameters(execParameterValues, "en-us");

                // start rendering a report
                byte[] reportBytes = rptExecute.Render(renderingFormat,   // report output format
                                                        out extention,
                                                        out mimeType,
                                                        out encoding,
                                                        out warnings,
                                                        out streamIDs);
                // write output to the targetLocationFile
                using (FileStream fileStream = File.OpenWrite(targetLocationFile))
                    fileStream.Write(reportBytes, 0, reportBytes.Length);
            catch (Exception e)
                throw e;

3. Call the procedure with the right parameter name and its value

When calling the procedure, the report parameter name must be the one you are using in Name field inside your SSRS report. 

Pass "CustomerID" in Name field of Report Parameter

// check your report location in the server
// the location of your report will look like this
reportLocation = "/Reports/Your Reports Folder/Your Report File Name";

// define a new hashtable and pass report parameter and its value in this way
userParamValues["CustomerID"] = "ABC123";

// target location with a full path
targetLocationFile = "testReportOutput.PDF";

// rendering format
renderingFormat = "PDF";

// use this procedure
Rpt_GenerateReport(string reportLocation, Hashtable userParamValues, string targetLocationFile, string renderingFormat)