我正在尝试创建一个Web,该API可以将样式化的HTML文件转换为PDF。
我正在使用TuesPechkin,并将我的应用程序安装到IIS中(作为32位应用程序:我修改了应用程序池,使其以32位模式运行)。
IIS8.5正在Windows 2012 R2上运行。
PDFConversion类在C#中:
using System.Drawing.Printing;
using System.IO;
using TuesPechkin;
namespace PDFApi
{
public class PDFcreator
{
public void convert(string path, string uri)
{
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));
var document = new HtmlToPdfDocument
{
GlobalSettings =
{
ProduceOutline = true,
DocumentTitle = "Converted Form",
PaperSize = PaperKind.A4,
Margins =
{
All = 1.375,
Unit = Unit.Centimeters
}
},
Objects =
{
new ObjectSettings { RawData = File.ReadAllBytes(uri) }
}
};
byte[] pdfBuf = converter.Convert(document);
FileStream fs = new FileStream(path, FileMode.Create);
fs.Write(pdfBuf, 0, pdfBuf.Length);
fs.Close();
}
}
}主计长如下:
[Route("converthtml")]
[HttpPost]
[MIMEContentFilter]
public async Task<HttpResponseMessage> ConvertHtml()
{
string temppath = System.IO.Path.GetTempPath();
var streamProvider = new MultipartFormDataStreamProvider(temppath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
string filepath = streamProvider.FileData.Select(entry => entry.LocalFileName.Replace(temppath + "\\", "")).First<string>();
string pdfpath = System.IO.Path.GetTempFileName();
pdfpath = pdfpath.Substring(0, pdfpath.LastIndexOf('.')) + ".pdf";
new PDFcreator().convert(pdfpath, filepath);
var stream = new FileStream(pdfpath, FileMode.Open);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}这里有点奇怪:在Fiddler中进行实验,发送一个文件一次就会立即返回PDF。然而,随后的所有帖子都会让Fiddler绞尽脑汁。检查任务管理器显示此任务的CPU和内存分别跳转13.5%和96 up。
在成功运行时,Temp文件夹(存储文件的位置)将包含三个文件:原始上传的文件(以类似GUID的名称存储)、通过wkHtmlToPdf生成的文件(形式为"wktemp-")和生成的pdf (作为tempXXXX.pdf)。在挂起的情况下,只能找到第一个文件,表明问题在wkHtmlToPdf本身的某个地方。
然而,真正的问题是当过程在任务管理器中被手动杀死时,API成功地完成,返回pdf,完全创建!
如果重置IIS,进程将返回原始状态;新尝试将正常工作。
显然,每次调用后重置IIS几乎是不可行的,而且每次都手动终止进程.
这个问题有什么解决办法吗?
发布于 2020-06-17 11:40:16
很重要-
@toshkata-tonev的答案帮助了我,但是当很多会话使用这个功能时,我们的服务器就崩溃了,因为CPU太多了!
问题是,所有会话都应该将该过程作为静态共享函数共享。
所以这是我的解决办法:
实现:在应用程序中创建一个静态类:
public static class TuesPechkinInitializerService {
private static string staticDeploymentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf");
public static void CreateWkhtmltopdfPath()
{
if (Directory.Exists(staticDeploymentPath) == false)
{
Directory.CreateDirectory(staticDeploymentPath);
}
}
public static IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new StaticDeployment(staticDeploymentPath)
)
)
);
}在GLOBAL.asax中,我在项目开始时初始化该类:
TuesPechkinInitializerService.CreateWkhtmltopdfPath();和使用它:
HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings(),
Objects =
{
new ObjectSettings
{
ProduceLocalLinks = true,
ProduceForms = true,
HtmlText = htmlContent
}
}
};
byte[] pdfDocumentData = TuesPechkinInitializerService.converter.Convert(pdfDocument);这得益于:
发布于 2015-10-13 15:56:34
编辑:非常重要-这个答案有很多的选票,但不是完整的。检查the marked solution
var tempFolderDeployment = new TempFolderDeployment();
var win32EmbeddedDeployment = new Win32EmbeddedDeployment(tempFolderDeployment);
var remotingToolset = new RemotingToolset<PdfToolset>(win32EmbeddedDeployment);
var converter =
new ThreadSafeConverter(remotingToolset);
byte[] pdfBuf = converter.Convert(document);
remotingToolset.Unload();卸载remotingToolset将防止挂起RemotingToolset.Unload();
发布于 2015-03-24 13:00:59
看起来您使用的是WkHtmlToPdf 64位,您已经安装了32位1位。
你应该改变:
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));至
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new TempFolderDelpoyment())));https://stackoverflow.com/questions/28037517
复制相似问题