好了,我又有一个困扰我的问题。我有一些代码可以将DOC文件转换为PNG文件。当我在本地主机上执行此操作时,图像是正常的。当我将相同的代码放在实时服务器上时,图像非常小(与我获得DOC文件的DOT文件大小相同,基本上DOT被填充并转换为DOC)。现在…这是最疯狂的部分。如果我以管理员身份登录主机服务器,然后访问实时网站,即使我从iPhone访问该网站,图像也会又大又清晰。一旦我退出主机服务器并刷新活动页面,图像就又变小了。这是我用来将DOC转换为PNG的代码。顺便说一句,如果我使用方法2,我可以使图像更大,分辨率更高,但是字体不合适。
private void ConvertDocToPNG(string startupPath, string filename1)
{
var docPath = Path.Combine(startupPath, filename1);
Application app = new Application();
Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
app.Visible = false;
doc = app.Documents.Open(docPath);
app.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateMaximize;
app.ActiveWindow.ActivePane.View.Zoom.Percentage = 100;
doc.ShowGrammaticalErrors = false;
doc.ShowRevisions = false;
doc.ShowSpellingErrors = false;
//Opens the word document and fetch each page and converts to image
foreach (Microsoft.Office.Interop.Word.Window window in doc.Windows)
{
foreach (Microsoft.Office.Interop.Word.Pane pane in window.Panes)
{
for (var i = 1; i <= pane.Pages.Count; i++)
{
Microsoft.Office.Interop.Word.Page page = null;
bool populated = false;
while (!populated)
{
try
{
// This !@#$ variable won't always be ready to spill its pages. If you step through
// the code, it will always work. If you just execute it, it will crash. So what
// I am doing is letting the code catch up a little by letting the thread sleep
// for a microsecond. The second time around, this variable should populate ok.
page = pane.Pages[i];
populated = true;
}
catch (COMException ex)
{
Thread.Sleep(1);
}
}
var bits = page.EnhMetaFileBits;
var target = Path.Combine(startupPath + "\", string.Format("{1}_page_{0}", i, filename1.Split('.')[0]));
try
{
using (var ms = new MemoryStream((byte[])(bits)))
{
var image = System.Drawing.Image.FromStream(ms);
var pngTarget = Path.ChangeExtension(target, "png");
// Method 2
image.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
// Another way to save it using custom size
//float width = Convert.ToInt32(hfIdCardMaxWidth.Value);
//float height = Convert.ToInt32(hfIdCardMaxHeight.Value);
//float scale = Math.Min(width / image.Width, height / image.Height);
//int resizedWidth = (int)Math.Round(image.Width * scale);
//int resizedHeight = (int)Math.Round(image.Height * scale);
//Bitmap myBitmap = new Bitmap(image, new Size(resizedWidth, resizedHeight));
//myBitmap.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
}
}
catch (System.Exception ex)
{
doc.Close(true, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(doc);
doc = null;
app.Quit(true, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(app);
app = null;
throw ex;
}
}
}
}
doc.Close(true, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(doc);
doc = null;
app.Quit(true, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(app);
app = null;
}
假设您以无人参与的方式使用互操作,那么可能会发生各种奇怪/意外的事情。我承认,我不知道为什么在不同的环境中给您的测试用例会遇到这些症状。我有一种强烈的感觉,无人看管是罪魁祸首。互操作在用户的登录上下文中运行,如果没有用户…嗯…是的。那么,如何绕过这个问题而不被人注意呢?首先想到的是使用OpenXML SDK。这是在无人看管的情况下操作办公室文件的安全方法。我自己用它生成无人值守的报告。
假设:
- 标准DOCX格式
- 文档包含文字/图片/样式/其他内容。它不仅仅是一袋图像(如果是,有更简单的方法来完成你需要的)
但是,你不能用OpenXML将文档转换为图像!我想到了一个变通办法,但这是没有经过测试。这个想法是将文档转换为html,然后渲染html并将其填充到图像中。
下面是一个使用OpenXML将word文档转换为HTML的方法:
一套大的电动工具,可以做各种方便的事情:http://powertools.codeplex.com/
您需要的特定模块:http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2014/01/30/transform-docx-to-html-css-with-high-fidelity-using-powertools-for-open-xml.aspx
这里有一个方便的库来渲染HTML并将其转储为图像:http://htmlrenderer.codeplex.com/
using (var ms = new MemoryStream((byte[])(bits)))
{
var emf = new Metafile(ms);
var scale = 400 / emf.HorizontalResolution;
var Width= emf.Width * scale;
var Height = emf.Height * scale;
System.Drawing.Bitmap b = new System.Drawing.Bitmap((Int32)Width, (Int32)Height);
var G = System.Drawing.Graphics.FromImage(b);
G.Clear(System.Drawing.Color.White);
G.DrawImage(emf, 0, 0, (float)Width, (float)Height);
b.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
}