• c# 导出带格式 图片 的Word文档·转


    原帖地址http://blog.sina.com.cn/s/blog_7016da1e0100wr2p.html

    VS2003已经装好,可以开始做了。

    第一步,做好Xml模板,这个直接在Word中另存为Xml格式就可,这个Xml可用Word打开,也要用记事本打开。

    第二步,用Word打开Xml模板,在表格中要填数据的地方做好标记,如图所示带格式图片的Word <wbr>文档导出(2)

    第三步,读取Xml模板

    string modePath = HttpContext.Current.Server.MapPath("同业对标专家库.xml");

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.Load(modePath);

    string docstr = xmlDoc.InnerXml.ToString();

    第四步,将模板中相应位置的值替换掉

    docstr = docstr.Replace("{branch_name}",this.LabelDW.Text);

    docstr = docstr.Replace("NAME",this.NAME.Value);

    docstr = docstr.Replace("SEX",this.SEX.Value);

    docstr = docstr.Replace("BIRTHDAY",this.BIRTHDAY.Value);

    docstr = docstr.Replace("PLACE",this.PLACE.Value);

    第五步,替换照片。照片导出是比较麻烦的部分。照片在Xml(Word转换)中以Base64编码保存,在上面的模板中,“userphoto”代表照片,在Xml中,userphoto的整个代码是<w:r><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/><wx:font wx:val="宋体"/></w:rPr><w:t>{userphoto}</w:t></w:r>

    替换照片时要把整个代码替换

    string userphotoXml = "<w:r><w:rPr><w:rFonts w:ascii=\"宋体\" w:h-ansi=\"宋体\" w:hint=\"fareast\" /><wx:font wx:val=\"宋体\" /></w:rPr><w:t>userphoto</w:t></w:r>";

     

    string PhotoXml = "<w:r><w:pict><w:binData w:name=\"wordml://02000001.jpg\" xml:space=\"preserve\">";

    //中间加Base64位编码的图片信息

    picStr = Convert.ToBase64String(pic);//pic为照片的byte[]格式,由数据库中读出

    PhotoXml +=picStr;

    PhotoXml +="</w:binData><v:shape id=\"_x0000_i1025\" type=\"#_x0000_t75\" style=\"75pt;height:100pt\"><v:imagedata src=\"wordml://02000001.jpg\" o:title=\"11163428_012248\"/> </v:shape></w:pict></w:r>";

     

    docstr = docstr.Replace(userphotoXml,PhotoXml);

     

    第六步,将Xml模板保存为Word

    xmlDoc.InnerXml = docstr;

    string filename = this.LabelDW.Text+"同业对标专家库.doc";

    filename = HttpContext.Current.Server.MapPath(filename);

    xmlDoc.Save(filename);

     

    第七步,导出文档

    private   void   FileDownload(string   FullFileName)

    {

         FileInfo   DownloadFile   =   new   FileInfo(FullFileName);  

         Response.Clear();

         Response.ClearHeaders();

         Response.Buffer= true;

         Response.ContentType= "application/octet-stream";

         Response.AppendHeader( "Content-Disposition ", "attachment;filename= "  +HttpUtility.UrlEncode("同业对标专家库压缩包.rar",System.Text.Encoding.UTF8));

     

         Response.AppendHeader( "Content-Length ",DownloadFile.Length.ToString());

         Response.WriteFile(DownloadFile.FullName);

         Response.Flush();

         Response.End();

    }

    至此,导出带格式Word完成,在本机运行成功。另外,多个文档打包导出,先用上述方法逐个生成文档,再打包保存,再导出下载。

    打包实现:

    在网上下了一个ICSharpCode.SharpZipLib.dll。

    using ICSharpCode.SharpZipLib.Zip;

    using ICSharpCode.SharpZipLib.Core;

    /// <summary>

             /// 压缩

              /// </summary>

             /// <param name="filesPath">要压缩的文件路径</param>

             /// <param name="zipFilePath">压缩完文件存放路径</param>

             private void CreateZipFile(string filesPath, string zipFilePath,string branchid)

             {

     

                  if (!Directory.Exists(filesPath))

                  {

                      

                  }

                  else

                  {

                       try

                       {

                                              //*****读取文件

                           string[] filenames = Directory.GetFiles(filesPath);

                           using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilePath)))

                           {

     

                                s.SetLevel(9); // 压缩级别 0-9

                                //s.Password = "123"; //Zip压缩文件密码

                                byte[] buffer = new byte[4096]; //缓冲区大小

                                foreach (string file in filenames)

                                {

                                     ZipEntry entry = new ZipEntry(Path.GetFileName(file));

                                     entry.DateTime = DateTime.Now;

                                     s.PutNextEntry(entry);

                                     using (FileStream fs = File.OpenRead(file))

                                     {

                                         buffer = new byte[fs.Length];

                                         int sourceBytes;

                                         do

                                         {

                                              sourceBytes = fs.Read(buffer, 0, buffer.Length);

                                              s.Write(buffer, 0, sourceBytes);

                                         } while (sourceBytes > 0);

                                    }

                                }

                                s.Finish();

                                s.Close();

                           }

                       }

                       catch (Exception ex)

                       {

                       }

                  }

             }

    打包下载也在本地运行成功,但布署到服务器(Win2003)上时,报错了,导出单个文档时不出下载保存对话框,而是将文档的XmL格式读取在页面上;导出压缩包时,报错The XML Page cannot be displayed带格式图片的Word <wbr>文档导出(2)

     

    布署在同事(Win XP)电脑上也报同样的错。我不能理解为什么,只能归结于系统不能识别文档到底是Xml格式还是Word格式,将Response.ContentType= "application/octet-stream";这句换成Word格式或Xml格式都不行,依然报错。折腾了很久,最后决定放弃下载文档的方式,将文档保存在数据库,从数据库中导出下载。

    ////将导出文件保存到数据库中

    SaveAsBLOB(filename,dr["branch_id"].ToString());

    private void SaveAsBLOB(string filename,string sid)

             {

                  string fileShortName = filename.Substring(filename.LastIndexOf('\\')+1);

                  System.Data.OracleClient.OracleConnection oc = new System.Data.OracleClient.OracleConnection(System.Configuration.ConfigurationSettings.AppSettings["DBConnString"].ToString());

                  byte[] buffer = null;

                  string sFileType = "",sFileName = "";

                 

                  FileStream fs = new FileStream(filename,FileMode.Open);

                  buffer = new byte[fs.Length];

                  fs.Read(buffer,0,(int)fs.Length);

                  sFileType="text/xml";

                  sFileName = TellHow.StringUtil.FileNameStringFunc.getFileName(filename);

     

                  try

                  {

     

                       System.Data.OracleClient.OracleCommand cmdSql = new System.Data.OracleClient.OracleCommand();

                       System.Text.StringBuilder sb = new System.Text.StringBuilder();

                       sb.Remove(0,sb.Length);

     

                       sb.AppendFormat(" update pu_zjinfo set AttachName='"+sFileName+"',AttachCont=:AttachCont");

                       sb.AppendFormat(" where branch_id='"+sid+"'");

     

                       cmdSql.CommandText = sb.ToString();

                       System.Data.OracleClient.OracleParameter attachCont=new System.Data.OracleClient.OracleParameter();

                       attachCont.Value=buffer;

                       attachCont.ParameterName="AttachCont";

                       attachCont.OracleType=System.Data.OracleClient.OracleType.Blob;

                       attachCont.Size=buffer.Length;

                       cmdSql.Parameters.Add(attachCont);

                       //cmdSql.Parameters.Add("@ImageData",OracleType.Blob,buffer.Length).Value = buffer;

                       cmdSql.Connection = oc;

                       oc.Open();

                       cmdSql.ExecuteNonQuery();

     

                       oc.Close();

                  }

                  catch(Exception e)

                  {

                       Response.Write("<script language='javascript'>");

                       Response.Write("alert('导出失败,原因是:"+e.Message+"!');");

                       Response.Write("</script>");

                  }

                           fs.Flush();

                  fs.Close();

             }

    这样,终于能够在WinXP 上实现下载。正准备更新到服务器时,又发现了一个新的问题,在弹出的文件下载框上多点击了几次取消后,再点击“导出”时

    带格式图片的Word <wbr>文档导出(2)

     

    报错:"该进程无法访问文件“D:\工作\DBPMIS\Experts\zip\南昌供电公司同业对标专家库.doc”,因为该文件正由另一进程使用。

    导出时生成在服务器的文档发生了死锁。可能在某处操作文档后未释放,解决方法:干脆在文档保存在数据库后删除,以绝后患。

    //保存到数据库后,将文件删除

    if(File.Exists( filename))

    File.Delete(filename);

    终于大功告成!

    最后的最后,客户使用时发现导出后的文档在“工作简历”栏没有换行,希望能换行。这个功能分析找到实现方法,“工作简历”用户输入时使用的TextArea控件,TextArea控件本身有换行符\r\n,根据换行符将内容分开,再按格式替换

    //工作简历,工作简历格式要求有换行

                                string gzjlStr = dr["GZJL"].ToString();//工作简历原值

                                gzjlStr = gzjlStr.Replace("\r\n","^");//先将换行符换成特殊符号

                                string[] gzjlArray = gzjlStr.Split('^');

     

                                string gzjl=gzjlArray[0];//用来替换“工作经历”(GZJL</w:t></w:r></w:p>)的字符串

     

                                gzjl+="</w:t></w:r></w:p>";

     

                                //从第二个开始,

                                for (int i =1;i<gzjlArray.Length;i++)

                                {

                                     gzjl+="<w:p><w:pPr><w:rPr><w:rFonts w:ascii=\"宋体\" w:h-ansi=\"宋体\" w:hint=\"fareast\"/><wx:font wx:val=\"宋体\"/></w:rPr></w:pPr>";

                                     //上一句表示换行

                                     gzjl+="<w:r><w:rPr><w:rFonts w:ascii=\"宋体\" w:h-ansi=\"宋体\" w:hint=\"fareast\"/><wx:font wx:val=\"宋体\"/></w:rPr><w:t>";

                                     gzjl += gzjlArray[i];

                                     gzjl+="</w:t></w:r></w:p>";

                                }

     

                                docstr= docstr.Replace("GZJL</w:t></w:r></w:p>",gzjl);

  • 相关阅读:
    打印二叉树中节点的所有祖先
    1.把2叉查找树转换成双向链表
    Linux下tar.xz结尾的文件的解压方法
    Floyd算法
    c缺陷与陷阱笔记-第七章 可移植性代码
    c缺陷与陷阱笔记-第六章 预处理器
    c缺陷与陷阱笔记-第四章 连接
    C语言小程序(四)、杨辉三角
    C语言小程序(三)、判断两个日期之差
    C语言小程序(二)、计算第二天日期
  • 原文地址:https://www.cnblogs.com/fcq121/p/2811377.html
Copyright © 2020-2023  润新知