Printing to PDF - file empty when needed

Posted by: heidi on 8 September 2017, 2:33 pm EST

  • Posted 8 September 2017, 2:33 pm EST

    Hi,

    I’m using the "FarPoint Spread for Windows Forms 5.0 and .Net Framework 3.5 - 5.0.3514.2008" in a C# app which is being built in Visual Studio 2008. My OS is Windows 7 Ultimate. I want to print the active sheet to pdf and then attach the pdf to an email, but at the point when I attach the pdf to the email, the pdf is empty. It appears that the pdf only gets written ‘after’ the email is generated. I’ve created a basic app that contains just the fpSpread and a button on a form and I get the same behaviour. I’ve included the code from my basic app below.

    …and before I get jumped on for not using “System.Net.Mail”, I can’t use it as I need to fire-up the active mail client (so users have access to their own address book) and the email that they send also needs to reside in their sent items folder.

    So…can anyone help?

    using
    System;
    using System.Diagnostics;
    using System.Windows.Forms;
    using FarPoint.Win.Spread;

    namespace fpSpreadPDFPrinting
    {



    public partial class Form1 : Form
    {



    public Form1()
    {



    InitializeComponent();


    }

    private void button1_Click(object sender, EventArgs e)
    {



    string strPDFFile = string.Format(@"c:\fpSpread{0}.pdf",DateTime.Now.ToString().Replace("/","-").Replace(":","-"));
    //Output the pdf
    try
    {



    FarPoint.Win.Spread.PrintInfo printset = new
    FarPoint.Win.Spread.PrintInfo();
    printset.PrintToPdf =
    true;
    printset.Orientation =
    PrintOrientation.Landscape;
    printset.ZoomFactor = 1;
    printset.PdfFileName = strPDFFile;
    fpSpread1.ActiveSheet.PrintInfo = printset;
    fpSpread1.PrintSheet(0);


    }
    catch (Exception ex1)
    {



    MessageBox.Show(ex1.Message, "Generating PDF", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    return;


    }
    //Email the pdf
    string toList = "me@you.com";
    string emailSubject = "Testing pdf printing";
    string emailMessage = "See attached pdf file.";
    string processCommand = "";
    Process myProcess = new Process();

    //Construct Command
    processCommand = string.Format("mailto:{0}", toList);
    if (!String.IsNullOrEmpty(emailSubject)) processCommand = string.Format("{0}?subject={1}", processCommand, emailSubject.Replace("&", "%26"));
    if (!String.IsNullOrEmpty(strPDFFile)) processCommand = string.Format("{0}&Attachment=\"{1}\"", processCommand, strPDFFile);
    if (!String.IsNullOrEmpty(emailMessage)) processCommand = string.Format("{0}&body={1}", processCommand, emailMessage.Replace("&", "%26"));

    //Start the Process
    try
    {



    myProcess.StartInfo.FileName = processCommand;
    myProcess.StartInfo.UseShellExecute =
    true;
    myProcess.StartInfo.RedirectStandardOutput =
    false;
    //If I break on the line below and check the pdf file size it is 0 KB.
    myProcess.Start();
    //The process generates an email with the pdf as an attachement but the
    //attachement is empty.
    //However, once the above line has executed, the pdf file is written.


    }
    catch (Exception ex2)
    {



    if (ex2.Message == "Access is Denied")
        throw new InvalidOperationException(String.Format("Unable to Open your default Email program to create an Email due to an unexpected Security related error: \r\n\r\n{0} ", ex2.Message));
    else
        throw new InvalidOperationException(String.Format("Unable to Open your default Email program to create an Email: \r\n\r\n{0} ", ex2.Message));


    }
    finally
    {



    myProcess.Dispose();


    }


    }


    }


    }

  • Replied 8 September 2017, 2:33 pm EST

    Hi Heidi,

    The printing happens in another thread, so it is not finished yet when your code to attach the file happens.  There is a way to make it print in the current thread, but it is not documented, and the XML summary tag  appears to be incorrect.  The method is called SafePrint and takes the FpSpread and sheet index as arguments.  The summary incorrect says that it makes the Spread print in another thread, but it actually does the opposite and makes it print in the current thread and finish before returning.  Here is some sample code that worked for me:

          string pdfFileName = Application.StartupPath + "\\test.pdf";

          if (File.Exists(pdfFileName))
            File.Delete(pdfFileName);
         
          fpSpread1_Sheet1.SetText(5, 5, "testing");
          fpSpread1_Sheet1.PrintInfo.PrintToPdf = true;
          fpSpread1_Sheet1.PrintInfo.PdfFileName = pdfFileName;
         
          fpSpread1.SafePrint(fpSpread1, 0);

          FileStream fs = new FileStream(pdfFileName, FileMode.Open);
          StreamReader sr = new StreamReader(fs);
          MessageBox.Show(sr.ReadToEnd());
          sr.Close();
          sr.Dispose();
          fs.Dispose();

  • Replied 8 September 2017, 2:33 pm EST

    Hi Seanl,

    Many thanks for your reply. We figured it was a thread issue so we devised our own intermediate fix. We refactored the code that does the emailing into it’s own method SendEmail(). We then added a timer which we start at the end of the button click event. When the timer fires, it calls SendEmail(). It works fine.

    I've just tried to change my code to use SafePrint but I don't seem to have the SafePrint method on my fpSpread object!  I’m using "FarPoint Spread for Windows Forms 5.0 and .Net Framework 3.5 - 5.0.3514.2008"

    Heidi

  • Replied 8 September 2017, 2:33 pm EST

    Hello,

    It should work, SafePrint() may not show as one of the methods with intellisense. But the given code should work fine as I have checked it with "FarPoint Spread for Windows Forms 5.0 and .Net Framework 3.5 - 5.0.3514.2008"

     

    Thanks,

     

  • Replied 8 September 2017, 2:33 pm EST

    Hi,

    I tried it and it works perfectly!

    Many thanks for your help,
    Heidi


     

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels