Beispiel #1
0
        private static string GetPageCommand(PdfConversionSettings config, string url, string tempPath = null, string temporaryFooterFilePath = null, string temporaryHeaderFilePath = null)
        {
            var pageOption = new StringBuilder("page");

            pageOption.Append($@" ""{url}"" ");

            // Page Options
            if (config.Zoom != null)
            {
                pageOption.AppendFormat("--zoom {0} ", config.Zoom);
            }

            // FOOTER
            if (string.IsNullOrWhiteSpace(temporaryFooterFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageFooterUrl) == false)
            {
                pageOption.AppendFormat("--footer-html  \"{0}\" ",
                                        string.IsNullOrWhiteSpace(config.PageFooterUrl) ? temporaryFooterFilePath : config.PageFooterUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlFooterArgs) == false)
                {
                    pageOption.Append(config.CustomWkHtmlFooterArgs);
                    pageOption.Append(" ");
                }
            }

            // HEADER
            if (string.IsNullOrWhiteSpace(temporaryHeaderFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageHeaderUrl) == false)
            {
                pageOption.AppendFormat("--header-html  \"{0}\" ",
                                        string.IsNullOrWhiteSpace(config.PageHeaderUrl) ? temporaryHeaderFilePath : config.PageHeaderUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlHeaderArgs) == false)
                {
                    pageOption.Append(config.CustomWkHtmlHeaderArgs);
                    pageOption.Append(" ");
                }
            }


            if (string.IsNullOrWhiteSpace(tempPath) == false)
            {
                pageOption.Append($@"""{tempPath}"" ");
            }

            return(pageOption.ToString());
        }
Beispiel #2
0
        /// <summary>
        /// Converts an HTML source input into a PDF output using the WkHTMLToPDF tool.
        /// The kitchen sink overload.
        /// </summary>
        /// <param name="config">Conversion</param>
        /// <param name="pdfOutputStream"></param>
        /// <param name="contentInputStream"></param>
        /// <param name="coverInputStream"></param>
        /// <param name="footerInputStream"></param>
        /// <param name="headerInputStream"></param>
        /// <param name="outputCallback"></param>
        public static void Convert(PdfConversionSettings config,
                                   Stream pdfOutputStream    = null,
                                   Stream contentInputStream = null,
                                   Stream coverInputStream   = null,
                                   Stream footerInputStream  = null,
                                   Stream headerInputStream  = null,
                                   Action <PdfConversionSettings, byte[]> outputCallback = null)
        {
            if (!File.Exists(config.PdfToolPath))
            {
                throw new ArgumentException($"File '{config.PdfToolPath}' not found. Check if wkhtmltopdf application is installed and set the correct location before calling this method.");
            }

            if (contentInputStream == null &&
                string.IsNullOrWhiteSpace(config.Content) &&
                string.IsNullOrWhiteSpace(config.ContentUrl) &&
                config.ContentUrls.Any() == false)
            {
                throw new ArgumentException("You must specify an input stream, static Content, Content Url, or Content Urls.");
            }

            if (pdfOutputStream == null &&
                string.IsNullOrWhiteSpace(config.OutputPath))
            {
                throw new ArgumentException("You must specify an output stream or an output path.");
            }

            string temporaryContentFilePath = Path.Combine(config.TempFilesPath, $"{Guid.NewGuid()}.html");

            string temporaryPdfFilePath = string.IsNullOrWhiteSpace(config.OutputPath) ?
                                          Path.Combine(config.TempFilesPath, $"{Guid.NewGuid()}.pdf") :
                                          config.OutputPath;

            // if no cover page html, url, or stream, don't set a temp path for the cover, footer, and/or header
            string temporaryCoverFilePath = coverInputStream == null &&
                                            string.IsNullOrWhiteSpace(config.PageCoverHtml) &&
                                            string.IsNullOrWhiteSpace(config.PageCoverUrl) ?
                                            null :
                                            Path.Combine(config.TempFilesPath, $"{Guid.NewGuid()}.html");
            string temporaryFooterFilePath = footerInputStream == null &&
                                             string.IsNullOrWhiteSpace(config.PageFooterHtml) &&
                                             string.IsNullOrWhiteSpace(config.PageFooterUrl) ?
                                             null :
                                             Path.Combine(config.TempFilesPath, $"{Guid.NewGuid()}.html");
            string temporaryHeaderFilePath = headerInputStream == null &&
                                             string.IsNullOrWhiteSpace(config.PageHeaderHtml) &&
                                             string.IsNullOrWhiteSpace(config.PageHeaderUrl) ?
                                             null :
                                             Path.Combine(config.TempFilesPath, $"{Guid.NewGuid()}.html");

            var commandOptions = BuildOptions(config,
                                              temporaryContentFilePath,
                                              temporaryPdfFilePath,
                                              temporaryCoverFilePath,
                                              temporaryHeaderFilePath,
                                              temporaryFooterFilePath);

            try
            {
                // COVER
                if (coverInputStream != null)
                {
                    using (var tempCoverFileStream = new FileStream(temporaryCoverFilePath, FileMode.CreateNew))
                    {
                        if (coverInputStream.CanSeek)
                        {
                            coverInputStream.Position = 0;
                        }
                        coverInputStream.CopyTo(tempCoverFileStream);
                    }
                }
                else if (string.IsNullOrWhiteSpace(config.PageCoverUrl) &&
                         string.IsNullOrWhiteSpace(config.PageCoverHtml) == false)
                {
                    // cover, if content is manually specified and no stream specified, then use the content
                    File.WriteAllText(temporaryCoverFilePath, config.PageCoverHtml);
                }

                // FOOTER
                if (footerInputStream != null)
                {
                    using (var tempFooterFileStream = new FileStream(temporaryFooterFilePath, FileMode.CreateNew))
                    {
                        if (footerInputStream.CanSeek)
                        {
                            footerInputStream.Position = 0;
                        }
                        footerInputStream.CopyTo(tempFooterFileStream);
                    }
                }
                else if (string.IsNullOrWhiteSpace(config.PageFooterUrl) &&
                         string.IsNullOrWhiteSpace(config.PageFooterHtml) == false)
                {
                    // footer, if content is manually specified and no stream specified, then use the content
                    File.WriteAllText(temporaryFooterFilePath, config.PageFooterHtml);
                }

                // HEADER
                if (headerInputStream != null)
                {
                    using (var tempHeaderFileStream = new FileStream(temporaryHeaderFilePath, FileMode.CreateNew))
                    {
                        if (headerInputStream.CanSeek)
                        {
                            headerInputStream.Position = 0;
                        }
                        headerInputStream.CopyTo(tempHeaderFileStream);
                    }
                }
                else if (string.IsNullOrWhiteSpace(config.PageHeaderUrl) &&
                         string.IsNullOrWhiteSpace(config.PageHeaderHtml) == false)
                {
                    // header, if content is manually specified and no stream specified, then use the content
                    File.WriteAllText(temporaryHeaderFilePath, config.PageHeaderHtml);
                }

                // CONTENT
                if (contentInputStream != null)
                {
                    // use the stream specified
                    using (var tempContentFileStream = new FileStream(temporaryContentFilePath, FileMode.CreateNew))
                    {
                        if (contentInputStream.CanSeek)
                        {
                            contentInputStream.Position = 0;
                        }
                        contentInputStream.CopyTo(tempContentFileStream);
                    }
                }
                else if (string.IsNullOrWhiteSpace(config.ContentUrl) &&
                         string.IsNullOrWhiteSpace(config.Content) == false)
                {
                    // use the content specified
                    using (var tempContentFileStream = new FileStream(temporaryContentFilePath, FileMode.CreateNew))
                    {
                        byte[] contentAsBytes = Encoding.UTF8.GetBytes(config.Content);
                        tempContentFileStream.Write(contentAsBytes, 0, contentAsBytes.Length);
                    }
                }

                // start process
                using (var process = new Process())
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo()
                    {
                        CreateNoWindow        = config.ProcessOptionCreateNoWindow,
                        FileName              = config.PdfToolPath,
                        Arguments             = commandOptions,
                        UseShellExecute       = config.ProcessOptionUseShellExecute,
                        RedirectStandardError = config.ProcessOptionRedirectStandardError
                    };

                    process.StartInfo = startInfo;
                    process.Start();

                    if (!process.WaitForExit(config.ExecutionTimeout))
                    {
                        throw new TimeoutException($"wkhtmltopdf execution time elapsed {config.ExecutionTimeout} ms.");
                    }

                    // check to make sure the generated file exists and the process didn't error
                    if (!File.Exists(temporaryPdfFilePath))
                    {
                        if (process.ExitCode != 0)
                        {
                            var error = startInfo.RedirectStandardError ?
                                        process.StandardError.ReadToEnd() :
                                        $"WkHTMLToPdf exited with code {process.ExitCode}.";
                            throw new InvalidDataException($"WkHTMLToPdf conversion of HTML data failed. Output: \r\n{error}");
                        }

                        throw new InvalidDataException($"WkHTMLToPdf conversion of HTML data failed. Output file '{temporaryPdfFilePath}' not found.");
                    }

                    if (pdfOutputStream != null)
                    {
                        using (Stream fs = new FileStream(temporaryPdfFilePath, FileMode.Open))
                        {
                            byte[] buffer = new byte[32 * 1024];
                            int    read;

                            while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                pdfOutputStream.Write(buffer, 0, read);
                            }
                        }
                    }

                    outputCallback?.Invoke(config, File.ReadAllBytes(temporaryPdfFilePath));
                }
            }
            finally
            {
                // if they specified an outputpath, don't kill the "temp" file
                if (string.IsNullOrWhiteSpace(config.OutputPath) && File.Exists(temporaryPdfFilePath))
                {
                    File.Delete(temporaryPdfFilePath);
                }
                if (File.Exists(temporaryContentFilePath))
                {
                    File.Delete(temporaryContentFilePath);
                }
                if (File.Exists(temporaryHeaderFilePath))
                {
                    File.Delete(temporaryHeaderFilePath);
                }
                if (File.Exists(temporaryFooterFilePath))
                {
                    File.Delete(temporaryFooterFilePath);
                }
                if (File.Exists(temporaryCoverFilePath))
                {
                    File.Delete(temporaryCoverFilePath);
                }
            }
        }
Beispiel #3
0
        private static string BuildOptions(PdfConversionSettings config,
                                           string temporaryContentFilePath,
                                           string temporaryPdfFilePath,
                                           string temporaryCoverFilePath,
                                           string temporaryHeaderFilePath,
                                           string temporaryFooterFilePath)
        {
            StringBuilder options = new StringBuilder();

            // GLOBAL OPTIONS
            if (string.IsNullOrWhiteSpace(config.CustomWkHtmlArgs))
            {
                if (config.Grayscale)
                {
                    options.Append("--grayscale ");
                }
                if (config.LowQuality)
                {
                    options.Append("--lowquality ");
                }
                if (config.Margins.Bottom != null)
                {
                    options.AppendFormat("--margin-bottom {0} ", config.Margins.Bottom);
                }
                if (config.Margins.Top != null)
                {
                    options.AppendFormat("--margin-top {0} ", config.Margins.Top);
                }
                if (config.Margins.Left != null)
                {
                    options.AppendFormat("--margin-left {0} ", config.Margins.Left);
                }
                if (config.Margins.Right != null)
                {
                    options.AppendFormat("--margin-right {0} ", config.Margins.Right);
                }
                if (config.Size != PdfPageSize.Default)
                {
                    options.AppendFormat("--page-size {0} ", config.Size.ToString());
                }
                if (config.Orientation != PdfPageOrientation.Default)
                {
                    options.AppendFormat("--orientation {0} ", config.Orientation.ToString());
                }
                if (string.IsNullOrWhiteSpace(config.Title) == false)
                {
                    options.AppendFormat("--title \"{0}\" ", config.Title.Replace("\"", ""));
                }
            }
            else
            {
                options.Append(config.CustomWkHtmlArgs);
                options.Append(" ");
            }

            // COVER
            if (string.IsNullOrWhiteSpace(temporaryCoverFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageCoverUrl) == false)
            {
                options.AppendFormat("cover  \"{0}\" ",
                                     string.IsNullOrWhiteSpace(config.PageCoverUrl) ? temporaryCoverFilePath : config.PageCoverUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlCoverArgs) == false)
                {
                    options.Append(config.CustomWkHtmlCoverArgs);
                    options.Append(" ");
                }
            }

            // TABLE OF CONTENTS
            if (config.GenerateToc)
            {
                options.Append("toc ");
                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlTocArgs) == false)
                {
                    options.Append(config.CustomWkHtmlTocArgs);
                    options.Append(" ");
                }
            }

            // PAGE
            if (config.ContentUrls.Any())
            {
                var count = config.ContentUrls.Count - 1;
                if (count < 0)
                {
                    count = 0;
                }

                foreach (var url in config.ContentUrls.Take(count))
                {
                    options.Append(GetPageCommand(config, url, null, temporaryFooterFilePath, temporaryHeaderFilePath));
                }

                options.Append(GetPageCommand(config, config.ContentUrls.Last(), temporaryPdfFilePath, temporaryFooterFilePath, temporaryHeaderFilePath));
            }
            else
            {
                options.Append(GetPageCommand(config, (string.IsNullOrWhiteSpace(config.ContentUrl) ? temporaryContentFilePath : config.ContentUrl), temporaryPdfFilePath, temporaryFooterFilePath, temporaryHeaderFilePath));
            }

            // PAGE OPTIONS
            if (string.IsNullOrWhiteSpace(config.CustomWkHtmlPageArgs) == false)
            {
                options.Append(config.CustomWkHtmlPageArgs);
            }

            return(options.ToString());
        }
Beispiel #4
0
        private static string BuildOptions(PdfConversionSettings config,
                                           string temporaryContentFilePath,
                                           string temporaryPdfFilePath,
                                           string temporaryCoverFilePath,
                                           string temporaryHeaderFilePath,
                                           string temporaryFooterFilePath)
        {
            StringBuilder options = new StringBuilder();

            // GLOBAL OPTIONS
            if (string.IsNullOrWhiteSpace(config.CustomWkHtmlArgs))
            {
                if (config.Grayscale)
                {
                    options.Append("--grayscale ");
                }
                if (config.LowQuality)
                {
                    options.Append("--lowquality ");
                }
                if (config.Margins.Bottom != null)
                {
                    options.AppendFormat("--margin-bottom {0} ", config.Margins.Bottom);
                }
                if (config.Margins.Top != null)
                {
                    options.AppendFormat("--margin-top {0} ", config.Margins.Top);
                }
                if (config.Margins.Left != null)
                {
                    options.AppendFormat("--margin-left {0} ", config.Margins.Left);
                }
                if (config.Margins.Right != null)
                {
                    options.AppendFormat("--margin-right {0} ", config.Margins.Right);
                }
                if (config.Size != PdfPageSize.Default)
                {
                    options.AppendFormat("--page-size {0}", config.Size.ToString());
                }
                if (config.Orientation != PdfPageOrientation.Default)
                {
                    options.AppendFormat("--orientation {0} ", config.Orientation.ToString());
                }
                if (string.IsNullOrWhiteSpace(config.Title) == false)
                {
                    options.AppendFormat("--title \"{0}\" ", config.Title.Replace("\"", ""));
                }
            }
            else
            {
                options.Append(config.CustomWkHtmlArgs);
                options.Append(" ");
            }

            // COVER
            if (string.IsNullOrWhiteSpace(temporaryCoverFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageCoverUrl) == false)
            {
                options.AppendFormat("cover  \"{0}\" ",
                                     string.IsNullOrWhiteSpace(config.PageCoverUrl) ? temporaryCoverFilePath : config.PageCoverUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlCoverArgs) == false)
                {
                    options.Append(config.CustomWkHtmlCoverArgs);
                    options.Append(" ");
                }
            }

            // FOOTER
            if (string.IsNullOrWhiteSpace(temporaryFooterFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageFooterUrl) == false)
            {
                options.AppendFormat("--footer-html  \"{0}\" ",
                                     string.IsNullOrWhiteSpace(config.PageFooterUrl) ? temporaryFooterFilePath : config.PageFooterUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlFooterArgs) == false)
                {
                    options.Append(config.CustomWkHtmlFooterArgs);
                    options.Append(" ");
                }
            }

            // HEADER
            if (string.IsNullOrWhiteSpace(temporaryHeaderFilePath) == false ||
                string.IsNullOrWhiteSpace(config.PageHeaderUrl) == false)
            {
                options.AppendFormat("--header-html  \"{0}\" ",
                                     string.IsNullOrWhiteSpace(config.PageHeaderUrl) ? temporaryHeaderFilePath : config.PageHeaderUrl);

                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlHeaderArgs) == false)
                {
                    options.Append(config.CustomWkHtmlHeaderArgs);
                    options.Append(" ");
                }
            }

            // TABLE OF CONTENTS
            if (config.GenerateToc)
            {
                options.Append("toc ");
                if (string.IsNullOrWhiteSpace(config.CustomWkHtmlTocArgs) == false)
                {
                    options.Append(config.CustomWkHtmlTocArgs);
                    options.Append(" ");
                }
            }

            // PAGE
            options.AppendFormat("page \"{1}\" \"{0}\" ",
                                 temporaryPdfFilePath,
                                 string.IsNullOrWhiteSpace(config.ContentUrl) ? temporaryContentFilePath : config.ContentUrl);

            // PAGE OPTIONS
            if (string.IsNullOrWhiteSpace(config.CustomWkHtmlPageArgs))
            {
                if (config.Zoom != null)
                {
                    options.AppendFormat("--zoom {0} ", config.Zoom);
                }
            }
            else
            {
                options.Append(config.CustomWkHtmlPageArgs);
            }

            return(options.ToString());
        }