Обратите внимание, что это не потокобезопасный на данный момент - я работаю над этим. Так что просто используйте монитор или что-то или замок.

ередать HTML в виде строки вместо URL в wkhtmltopdf, используя asp.net, c #?

 Eugene10 янв. 2011 г., 21:50
Не могли бы вы показать пример?
 Michael Todd10 янв. 2011 г., 21:49
Вероятно, было бы проще перенаправить стандартный ввод и передать строку таким образом. Вы также можете записать текст в файл (хотя это, конечно, не очень хорошо масштабируется).

Ответы на вопрос(3)

поэтому вам вообще не нужны файлы.

public static class Printer
{
    public const string HtmlToPdfExePath = "wkhtmltopdf.exe";

    public static bool GeneratePdf(string commandLocation, StreamReader html, Stream pdf, Size pageSize)
    {
        Process p;
        StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        psi.FileName = Path.Combine(commandLocation, HtmlToPdfExePath);
        psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note: that we tell wkhtmltopdf to be quiet and not run scripts
        psi.Arguments = "-q -n --disable-smart-shrinking " + (pageSize.IsEmpty? "" : "--page-width " + pageSize.Width +  "mm --page-height " + pageSize.Height + "mm") + " - -";

        p = Process.Start(psi);

        try {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;
            stdin.Write(html.ReadToEnd());
            stdin.Dispose();

            CopyStream(p.StandardOutput.BaseStream, pdf);
            p.StandardOutput.Close();
            pdf.Position = 0;

            p.WaitForExit(10000);

            return true;
        } catch {
            return false;

        } finally {
            p.Dispose();
        }
    }

    public static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
            output.Write(buffer, 0, read);
        }
    }
}
 Filip Cornelissen19 окт. 2011 г., 09:19
да, это лучше :)
 Filip Cornelissen05 сент. 2011 г., 16:02
нет нуждыблизко а такжеизбавиться Процесс, он делает то же самое. Просто утилизируйте его или поместите в конструкцию с использованием. То же самое касается потоков.
 Ulises22 янв. 2013 г., 21:49
+1 Отличный пост, я недавно писал об этом, используя похожий код:megustaulises.com/2012/12/...
 senthil08 мая 2013 г., 16:06
Великий пост это очень помогло
 Daniel Little17 окт. 2011 г., 01:21
Теперь только распоряжаться называется

что это старая статья, но я хочу, чтобы у будущих разработчиков была эта опция. У меня была такая же потребность, и идея запуска фонового процесса просто для того, чтобы получить PDF внутри веб-приложения, ужасна.

Вот еще один вариант:https://github.com/TimothyKhouri/WkHtmlToXDotNet

Это родная оболочка .NET для wkhtmltopdf.

Пример кода здесь:

var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");

Обратите внимание, что это не потокобезопасный на данный момент - я работаю над этим. Так что просто используйте монитор или что-то или замок.

вероятно, самый простой способ выполнить то, что вы пытаетесь сделать.

Один из способов перенаправления STDIN с помощью wkhtmltopdf (в ASP.Net) заключается в следующем:

    private void WritePDF(string HTML)
    {
        string inFileName,
                outFileName,
                tempPath;
        Process p;
        System.IO.StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        tempPath = Request.PhysicalApplicationPath + "temp\\";
        inFileName = Session.SessionID + ".htm";
        outFileName = Session.SessionID + ".pdf";

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.FileName = "c:\\Program Files (x86)\\wkhtmltopdf\\wkhtmltopdf.exe";
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note that we tell wkhtmltopdf to be quiet and not run scripts
        // NOTE: I couldn't figure out a way to get both stdin and stdout redirected so we have to write to a file and then clean up afterwards
        psi.Arguments = "-q -n - " + tempPath + outFileName;

        p = Process.Start(psi);

        try
        {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;

            stdin.Write(HTML);
            stdin.Close();

            if (p.WaitForExit(15000))
            {
                // NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
                Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
                //Response.WriteFile(tempPath + outFileName);
            }
        }
        finally
        {
            p.Close();
            p.Dispose();
        }

        // delete the pdf
        System.IO.File.Delete(tempPath + outFileName);
    }

Обратите внимание, что код выше предполагает, что естьтемпература каталог, доступный в каталоге вашего приложения. Кроме того, вы должны явно разрешить доступ на запись в этот каталог для учетной записи пользователя, используемой при запуске процесса IIS.

 smerlung11 февр. 2014 г., 14:47
Я не могу заставить это работать с ссылками на изображения и таблицы стилей. Это что возможно? Когда я запускаю командную строку с файлами на диске, это работает.
 Michael Todd11 февр. 2014 г., 16:27
@smerlung Убедитесь, что у веб-приложения есть доступ к файлам, на которые вы ссылаетесь. При запуске из командной строки вы работаете под своим логином; при запуске с веб-сервера вы используете учетную запись веб-сервера, который может не иметь доступа к используемым файлам. Также убедитесь, что путь к файлам имеет смысл и из этого места. Например, если вы ссылаетесь..\styles\style.css тогда должно бытьstyles каталог «выше», где вы запускаете программу, которая содержитstyle.css файл.
 smerlung11 февр. 2014 г., 17:48
Я получил это с помощью абсолютных путей. Но это не очень приятно. Я понимаю, что вы говорите, но моя проблема в том, что я не понимаю, где этот процесс "работает". Я пробовал разные варианты для WorkingDirectory, но не мог понять это?

Ваш ответ на вопрос