为解决在FCK里粘贴WORD文档图片不能存在服务器上的问题,今天特写个了用户控件
当然,如果不是存于FCK的value而是使用在其它地方也不错:)
编程思想
如果把wordf直接粘到fck编辑器的话地面的图片因为是本地路径所以无法显示,如果只粘了结构再把一张一张的图上传上去插入图片的话太累而且格式不好控制。
如果直接上传word文档是比较轻松的问题,我们知道word文档是可以直接保存成html的,而且会自动保存一个同名的.files文件放图片。所以想到先把word文件上传到服务器,再在服务器上把word另存成HTML。然后从html里读取源文件。再把服务器上的word文件和html删除就可以了。为了不产生更多的xxxxx.files文件夹,顺便处理把xxxxx.files里的图片移动到我们想要的存放图片的文件夹,然后修改html里的图片路径,这样同时也可以把xxxxx.files文件夹删除,这样也减少了些垃圾文件。
制作步骤
1.引用Microsoft.Office.Interop.Word;处理word事件
2.代码撰写(省了,下面有)
3.发现执行Microsoft.Office.Interop.Word有权限问题所以修改web.config文件在<system.web>配置节时里加入
<identity impersonate="true" />可以解决。
4.如果是后台使用,因为服务器文件删除会导致sesion丢失的问题所以需要特别处理一下sesion的问题,解决方法很多,所以我就不多说了,比如可以改用cookie,也可以修改<sessionState mode="StateServer" ....也可以sesion先存到ViewState,删除完了再读出来重新赋值
可以这样写
if (!IsPostBack)
{
Dictionary<string, object> dir = new Dictionary<string, object>();
foreach (string k in Session.Keys)
{
dir.Add(k, Session[k]);
}
ViewState["Session"] = dir;
}
if (ViewState["Session"] != null)
{
Dictionary<string, object> dir2=(Dictionary<string, object>)ViewState["Session"];
foreach (KeyValuePair<string, object> j in dir2)
{
Session[j.Key] = j.Value;
}
}
不过用ViewState也要类要能序列化,所以如果sesion里存有无法序列化的类是你要进行其它处理,其它方法聪明的你肯定也想得出,好了,不多说了,直接把代码粘上来吧(这里是用户控件.asxc如果加了个属性来赋值到FCK控件,如果你想直接用.aspx也是可以的,呵)
.asxc文件内容
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="UploadWord.ascx.cs" Inherits="UtilControl_UploadWord" %>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" οnclick="Button1_Click"
Text="载入word档案" />
.cs内容
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using Microsoft.Office.Interop.Word;
using System.Text.RegularExpressions;
public partial class UtilControl_UploadWord : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
if (this.FileUpload1.HasFile) //如果有上传文件执行
{
string xxx = Guid.NewGuid().ToString();//为服务器上的word文件
this.FileUpload1.SaveAs(MapPath("~/upload/" + xxx + ".doc"));
WordToHtml(xxx);
}
}
}
private void WordToHtml(string FileName)
{
string wordFileName = MapPath("~/upload/" + FileName + ".doc");
Microsoft.Office.Interop.Word.ApplicationClass word = new Microsoft.Office.Interop.Word.ApplicationClass();
Type wordType = word.GetType();
Documents docs = word.Documents; //打开文件
Type docsType = docs.GetType();
Document doc = (Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, docs, new Object[] { wordFileName, true, true }); //转换格式,另存为
Type docType = doc.GetType(); string wordSaveFileName = wordFileName.ToString();
string strSaveFileName = wordSaveFileName.Substring(0, wordSaveFileName.LastIndexOf('.')) + ".html";
//object saveFileName = (object)strSaveFileName;
docType.InvokeMember("SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, doc, new object[] { strSaveFileName, WdSaveFormat.wdFormatFilteredHTML });
docType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, doc, null); //退出 Word
wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, word, null);
string contentstr = File.ReadAllText(strSaveFileName, System.Text.Encoding.Default);
if (File.Exists(wordFileName))
{
File.Delete(wordFileName);
}
string imagefiles = MapPath("~/upload/" + FileName + ".files");
if (Directory.Exists(imagefiles))
{
//移动图片到upload
foreach (string k in Directory.GetFiles(imagefiles))
{
string newimg = k.Replace(FileName + ".files//", FileName);
File.Move(k, newimg);
}
System.IO.Directory.Delete(imagefiles);//删除图片文件
}
Match m = Regex.Match(contentstr, @"</s*body[^>]*>([/s/S]+?)</s*///s*body/s*>", RegexOptions.IgnoreCase);
if (m.Success)
{
FCKeditor.Value = m.Value.Replace(FileName + ".files/", ResolveUrl("~/upload/" + FileName)).Replace("<body","<div").Replace("</body>","</div>");
}
File.Delete(strSaveFileName);//删除html文件
}
public FredCK.FCKeditorV2.FCKeditor FCKeditor
{
get;
set;
}
}