У меня есть класс С#, который берет HTML и конвертирует его в PDF с помощью wkhtmltopdf.
Как вы увидите ниже, я создаю 3 файла PDF - альбомную, книжную и комбинированную из двух.
Объект properties
содержит HTML в виде строки и аргумент для ландшафта/портрета.
System.IO.MemoryStream PDF = new WkHtmlToPdfConverter().GetPdfStream(properties);
System.IO.FileStream file = new System.IO.FileStream("abc_landscape.pdf", System.IO.FileMode.Create);
PDF.Position = 0;
properties.IsHorizontalOrientation = false;
System.IO.MemoryStream PDF_portrait = new WkHtmlToPdfConverter().GetPdfStream(properties);
System.IO.FileStream file_portrait = new System.IO.FileStream("abc_portrait.pdf", System.IO.FileMode.Create);
PDF_portrait.Position = 0;
System.IO.MemoryStream finalStream = new System.IO.MemoryStream();
PDF.CopyTo(finalStream);
PDF_portrait.CopyTo(finalStream);
System.IO.FileStream file_combined = new System.IO.FileStream("abc_combined.pdf", System.IO.FileMode.Create);
try
{
PDF.WriteTo(file);
PDF.Flush();
PDF_portrait.WriteTo(file_portrait);
PDF_portrait.Flush();
finalStream.WriteTo(file_combined);
finalStream.Flush();
}
catch (Exception)
{
throw;
}
finally
{
PDF.Close();
file.Close();
PDF_portrait.Close();
file_portrait.Close();
finalStream.Close();
file_combined.Close();
}
PDF файлы "abc_landscape.pdf" и "abc_portrait.pdf" генерируются правильно, как и ожидалось, но операция завершается неудачно, когда я пытаюсь объединить их в третий pdf (abc_combined.pdf).
Я использую MemoryStream
для предварительного слияния, и во время отладки я вижу, что finalStream.length
равен сумме двух предыдущих PDF файлов. Но когда я пытаюсь открыть PDF файл, я вижу содержимое только одного из двух PDF файлов.
То же самое можно увидеть ниже:
Кроме того, когда я пытаюсь закрыть файл "abc_combined.pdf", мне предлагается сохранить его, чего не происходит с двумя другими PDF файлами.
Ниже приведены некоторые вещи, которые я уже опробовал, но безрезультатно:
- Измените CopyTo() на WriteTo()
- Объедините один и тот же PDF файл (альбомный или книжный) с самим собой
В случае, если это требуется, ниже приведена разработка методаGetPdfStream()
.
var htmlStream = new MemoryStream();
var writer = new StreamWriter(htmlStream);
writer.Write(htmlString);
writer.Flush();
htmlStream.Position = 0;
return htmlStream;
Process process = Process.Start(psi);
process.EnableRaisingEvents = true;
try
{
process.Start();
process.BeginErrorReadLine();
var inputTask = Task.Run(() =>
{
htmlStream.CopyTo(process.StandardInput.BaseStream);
process.StandardInput.Close();
});
// Copy the output to a memorystream
MemoryStream pdf = new MemoryStream();
var outputTask = Task.Run(() =>
{
process.StandardOutput.BaseStream.CopyTo(pdf);
});
Task.WaitAll(inputTask, outputTask);
process.WaitForExit();
// Reset memorystream read position
pdf.Position = 0;
return pdf;
}
catch (Exception ex)
{
throw ex;
}
finally
{
process.Dispose();
}