调用word的com组件将400条数据导入word表格中耗时10分钟简直不能忍受,使用NPOI组件耗时4秒钟.但是NPOI中替换书签内容的功能不知道是不支持还是没找到.

辅助类 Excel表格数据与DataTable互转:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using NPOI.SS.UserModel;
  6. using NPOI.XSSF.UserModel;
  7. using NPOI.HSSF.UserModel;
  8. using System.IO;
  9. using System.Data;
  10.  
  11. namespace Utils
  12. {
  13. //http://www.cnblogs.com/luxiaoxun/p/3374992.html
  14. public class ExcelDataTableConverter : IDisposable
  15. {
  16. private string fileName = null; //文件名
  17. private IWorkbook workbook = null;
  18. private FileStream fs = null;
  19. private bool disposed;
  20.  
  21. public ExcelDataTableConverter(string fileName)
  22. {
  23. this.fileName = fileName;
  24. disposed = false;
  25. }
  26.  
  27. /// <summary>
  28. /// 将DataTable数据导入到excel中
  29. /// </summary>
  30. /// <param name="data">要导入的数据</param>
  31. /// <param name="isColumnWritten">DataTable的列名是否要导入</param>
  32. /// <param name="sheetName">要导入的excel的sheet的名称</param>
  33. /// <returns>导入数据行数(包含列名那一行)</returns>
  34. public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten)
  35. {
  36. int i = 0;
  37. int j = 0;
  38. int count = 0;
  39. ISheet sheet = null;
  40.  
  41. fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  42. if (fileName.IndexOf(".xlsx") > 0) // 2007版本
  43. workbook = new XSSFWorkbook();
  44. else if (fileName.IndexOf(".xls") > 0) // 2003版本
  45. workbook = new HSSFWorkbook();
  46.  
  47. try
  48. {
  49. if (workbook != null)
  50. {
  51. sheet = workbook.CreateSheet(sheetName);
  52. }
  53. else
  54. {
  55. return -1;
  56. }
  57.  
  58. if (isColumnWritten == true) //写入DataTable的列名
  59. {
  60. IRow row = sheet.CreateRow(0);
  61. for (j = 0; j < data.Columns.Count; ++j)
  62. {
  63. row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
  64. }
  65. count = 1;
  66. }
  67. else
  68. {
  69. count = 0;
  70. }
  71.  
  72. for (i = 0; i < data.Rows.Count; ++i)
  73. {
  74. IRow row = sheet.CreateRow(count);
  75. for (j = 0; j < data.Columns.Count; ++j)
  76. {
  77. row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
  78. }
  79. ++count;
  80. }
  81. workbook.Write(fs); //写入到excel
  82. return count;
  83. }
  84. catch (Exception ex)
  85. {
  86. Console.WriteLine("Exception: " + ex.Message);
  87. return -1;
  88. }
  89. }
  90.  
  91. /// <summary>
  92. /// 将excel中的数据导入到DataTable中
  93. /// </summary>
  94. /// <param name="sheetName">excel工作薄sheet的名称</param>
  95. /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
  96. /// <returns>返回的DataTable</returns>
  97. public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
  98. {
  99. ISheet sheet = null;
  100. DataTable data = new DataTable();
  101. int startRow = 0;
  102. try
  103. {
  104. fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
  105. if (fileName.IndexOf(".xlsx") > 0) // 2007版本
  106. workbook = new XSSFWorkbook(fs);
  107. else if (fileName.IndexOf(".xls") > 0) // 2003版本
  108. workbook = new HSSFWorkbook(fs);
  109.  
  110. if (sheetName != null)
  111. {
  112. sheet = workbook.GetSheet(sheetName);
  113. if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
  114. {
  115. sheet = workbook.GetSheetAt(0);
  116. }
  117. }
  118. else
  119. {
  120. sheet = workbook.GetSheetAt(0);
  121. }
  122. if (sheet != null)
  123. {
  124. IRow firstRow = sheet.GetRow(0);
  125. int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
  126.  
  127. if (isFirstRowColumn)
  128. {
  129. for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
  130. {
  131. ICell cell = firstRow.GetCell(i);
  132. if (cell != null)
  133. {
  134. string cellValue = cell.StringCellValue;
  135. if (cellValue != null)
  136. {
  137. DataColumn column = new DataColumn(cellValue);
  138. data.Columns.Add(column);
  139. }
  140. }
  141. }
  142. startRow = sheet.FirstRowNum + 1;
  143. }
  144. else
  145. {
  146. startRow = sheet.FirstRowNum;
  147. }
  148.  
  149. //最后一列的标号
  150. int rowCount = sheet.LastRowNum;
  151. for (int i = startRow; i <= rowCount; ++i)
  152. {
  153. IRow row = sheet.GetRow(i);
  154. if (row == null) continue; //没有数据的行默认是null       
  155.  
  156. DataRow dataRow = data.NewRow();
  157. for (int j = row.FirstCellNum; j < cellCount; ++j)
  158. {
  159. if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
  160. {
  161. //dataRow[j] = row.GetCell(j).ToString(); //19890603会显示成MIDB(C2,7,6)
  162. dataRow[j] = row.GetCell(j).StringCellValue;
  163. }
  164. }
  165. data.Rows.Add(dataRow);
  166. }
  167. }
  168.  
  169. return data;
  170. }
  171. catch (Exception ex)
  172. {
  173. Console.WriteLine("Exception: " + ex.Message);
  174. return null;
  175. }
  176. }
  177.  
  178. public void Dispose()
  179. {
  180. Dispose(true);
  181. GC.SuppressFinalize(this);
  182. }
  183.  
  184. protected virtual void Dispose(bool disposing)
  185. {
  186. if (!this.disposed)
  187. {
  188. if (disposing)
  189. {
  190. if (fs != null)
  191. fs.Close();
  192. }
  193.  
  194. fs = null;
  195. disposed = true;
  196. }
  197. }
  198. }
  199. }

调用:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using NPOI.XWPF.UserModel;
  10. using NPOI.OpenXmlFormats.Wordprocessing;
  11. using System.IO;
  12.  
  13. namespace WordNPOI
  14. {
  15. public partial class Form1 : Form
  16. {
  17. public Form1()
  18. {
  19. InitializeComponent();
  20. }
  21.  
  22. XWPFDocument doc = new XWPFDocument();
  23.  
  24. private void Form1_Load(object sender, EventArgs e)
  25. {
  26.  
  27. }
  28.  
  29. private void button1_Click(object sender, EventArgs e)
  30. {
  31. Utils.ExcelDataTableConverter edc = new Utils.ExcelDataTableConverter("60岁以上人员.xlsx");
  32. DataTable dt = edc.ExcelToDataTable("sheet1", true);
  33.  
  34. int rowCount = dt.Rows.Count;
  35. int columnCount = dt.Columns.Count;
  36.  
  37. //创建段落对象
  38. XWPFParagraph p1 = doc.CreateParagraph();
  39. //创建run对象
  40. //本节提到的所有样式都是基于XWPFRun的,
  41. //你可以把XWPFRun理解成一小段文字的描述对象,
  42. //这也是Word文档的特征,即文本描述性文档。
  43. //来自Tony Qu http://tonyqus.sinaapp.com/archives/609
  44. XWPFRun r1 = p1.CreateRun();
  45. r1.SetBold(true);
  46. r1.SetText("数据导出demo");
  47. r1.SetBold(true);
  48. r1.FontFamily = "宋体";
  49. r1.FontSize = 26;
  50. //r1.SetFontFamily("Arial");//设置雅黑字体
  51. //创建表格对象,行 列
  52. XWPFTable table = doc.CreateTable(rowCount + 1, columnCount);
  53.  
  54. //添加列头
  55. for (int i = 0; i < columnCount; i++)
  56. {
  57. var ctt = table.GetRow(0).GetCell(i).GetCTTc();
  58. var tcPr = ctt.AddNewTcPr();
  59. tcPr.tcW = new CT_TblWidth();
  60. tcPr.tcW.w = "6000";//单元格宽 单位是EMU,1英寸= 914400 EMU http://bbs.csdn.net/topics/390906055
  61. tcPr.tcW.type = ST_TblWidth.dxa;
  62. //table.SetColumnWidth(i, 5500); //无效果 特定数字5500又太大 貌似要设置为n*256
  63.  
  64. //设置单元格字体 样式 http://www.tuicool.com/articles/JFZzUj
  65. var p = table.GetRow(0).GetCell(i).AddParagraph();
  66.  
  67. XWPFRun r = p.CreateRun();
  68. r.FontFamily = "宋体";
  69. r.FontSize = 10;
  70. r.SetBold(true);
  71. r.SetText(dt.Columns[i].ColumnName);
  72. }
  73.  
  74. for (int i = 1; i < rowCount; i++)
  75. {
  76. for (int j = 0; j < columnCount; j++)
  77. {
  78. string tem = dt.Rows[i][j].ToString();
  79. table.GetRow(i).GetCell(j).SetText(dt.Rows[i][j].ToString());
  80. }
  81. }
  82.  
  83. //插入图片
  84. var gfs = new FileStream("1.png", FileMode.Open, FileAccess.Read);
  85. var gp = doc.CreateParagraph();
  86. gp.Alignment = ParagraphAlignment.CENTER; //居中
  87. var gr = gp.CreateRun();
  88. gr.AddPicture(gfs, (int)PictureType.JPEG, "1.png", 1000000, 1000000); //1000000 差不多100像素多一点
  89. gfs.Close();
  90.  
  91. var gp1 = doc.CreateParagraph();
  92. gp1.CreateRun().SetText("The End");
  93.  
  94. //bookmark书签
  95.  
  96. var items = doc.Paragraphs[0].Document.BodyElements;
  97.  
  98. //CT_Bookmark b = new CT_Bookmark();
  99.  
  100. //CT_Bookmark ctBookmark = doc.Paragraphs[0].GetBookmarkStartArray(0);
  101.  
  102. //foreach (CT_Bookmark bookmark in doc.Paragraphs[0].GetCTP().GetBookmarkStartList()) //网上的代码,发现找不到这个方法
  103. //{
  104. // Assert.AreEqual("poi", bookmark.name);
  105. //}
  106.  
  107. //书签0开始
  108. int m_bookId = 0;//同一段内有多个书签,需要不同的Id,不同段的书签Id可以相同
  109.  
  110. CT_P m_p = doc.Document.body.AddNewP();
  111.  
  112. m_p.AddNewPPr().AddNewJc().val = ST_Jc.both;
  113.  
  114. m_p.AddNewPPr().AddNewSpacing().line = "400";//固定行距20磅
  115.  
  116. m_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.exact;
  117.  
  118. m_p.Items = new System.Collections.ArrayList();
  119.  
  120. CT_Bookmark m_ctbook1 = new CT_Bookmark();
  121.  
  122. m_bookId = m_p.Items.Count;
  123.  
  124. m_ctbook1.id = m_bookId.ToString(); //"0";
  125.  
  126. m_ctbook1.name = "NPOI1";//书签名,超链接用
  127.  
  128. m_p.Items.Add(m_ctbook1);
  129.  
  130. m_p.ItemsElementName = new List<ParagraphItemsChoiceType>();
  131.  
  132. m_p.ItemsElementName.Add(ParagraphItemsChoiceType.bookmarkStart);
  133.  
  134. m_p.AddNewR().AddNewT().Value = "1、NPOI介绍";
  135.  
  136. //书签0结束
  137.  
  138. m_ctbook1 = new CT_Bookmark();
  139.  
  140. m_ctbook1.id = m_bookId.ToString();//"0";
  141.  
  142. m_p.Items.Add(m_ctbook1);
  143.  
  144. m_p.ItemsElementName.Add(ParagraphItemsChoiceType.bookmarkEnd);
  145.  
  146. //获得书签
  147. int pcount = doc.Document.body.ItemsElementName.Count();
  148. List<CT_Bookmark> bkList = new List<CT_Bookmark>();
  149. for (int i = 0; i < pcount; i++)
  150. {
  151. var ctp = doc.Document.body.GetPArray(i);
  152. if (ctp!=null)
  153. {
  154. var tempBookMarkList = ctp.GetBookmarkStartList();
  155. bkList.AddRange(tempBookMarkList);
  156. }
  157. }
  158.  
  159. foreach (var bookMark in bkList)
  160. {//替换书签内容?????????????????找不到示例代码还是不支持此功能?
  161. bookMark.colFirst = "1";
  162. bookMark.colLast = "2";
  163. bookMark.displacedByCustomXmlSpecified = true;
  164.  
  165. MessageBox.Show(bookMark.name);
  166.  
  167. }
  168.  
  169. //保存文件到磁盘
  170. FileStream out1 = new FileStream("simpleTable.docx", FileMode.OpenOrCreate);
  171. doc.Write(out1);
  172. out1.Close();
  173.  
  174. MessageBox.Show("done");
  175. }
  176. }
  177. }

关于宽高设置:

http://www.oschina.net/code/snippet_222150_9780

 
  1. Excel中,单元格的宽度其实就是列的宽度,因为Excel假设这一列的单元格的宽度肯定一致。所以要设置单元格的宽度,我们就得从列的宽度下手,HSSFSheet有个方法叫SetColumnWidth,共有两个参数:一个是列的索引(从0开始),一个是宽度。
  2. 现在假设你要设置B列的宽度,就可以用下面的代码:
  3. HSSFWorkbook hssfworkbook = new HSSFWorkbook();
  4. HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");
  5. sheet1.SetColumnWidth(1, 100 * 256);
  6. 这里你会发现一个有趣的现象,SetColumnWidth的第二个参数要乘以256,这是怎么回事呢?其实,这个参数的单位是1/256个字符宽度,也就是说,这里是把B列的宽度设置为了100个字符。
  7. 刚才说的是如何设置,那如何去读取一个列的宽度呢?直接用GetColumnWidth方法,这个方法只有一个参数,那就是列的索引号。如下所示:
  8. int col1width = sheet1.GetColumnWidth(1);
  9.  
  10. 说完宽度,我们来说高度,在Excel中,每一行的高度也是要求一致的,所以设置单元格的高度,其实就是设置行的高度,所以相关的属性也应该在HSSFRow上,它就是HSSFRow.HeightHeightInPoints,这两个属性的区别在于HeightInPoints的单位是点,而Height的单位是1/20个点,所以Height的值永远是HeightInPoints20倍。
  11. 要设置第一行的高度,可以用如下代码:
  12. sheet1.CreateRow(0).Height = 200*20;
  13. 或者
  14. sheet1.CreateRow(0).HeightInPoints = 200;
  15. 如果要获得某一行的行高,可以直接拿HSSFRow.Height属性的返回值。
  16.  
  17. 你可能觉得一行一行设置行高或者一列一列设置列宽很麻烦,那你可以考虑使用HSSFSheet.DefaultColumnWidthHSSFSheet.DefaultRowHeightHSSFSheet.DefaultRowHeightInPoints属性。
  18. 一旦设置了这些属性,如果某一行或者某一列没有设置宽度,就会使用默认宽度或高度。代码如下:
  19. sheet1.DefaultColumnWidth=100*256;
  20. sheet1.DefaultRowHeight=30*20;

版权声明:本文为博主原创文章,未经博主允许不得转载。

C#调用NPOI组件读取excel表格数据转为datatable写入word表格中并向word中插入图片/文字/书签 获得书签列表的更多相关文章

  1. C#调用NPOI组件导出Excel表格

    把一个List集合的数据导出到Excel表格中 public static string RenderToExcel<T>(List<T> datas) { MemoryStr ...

  2. 利用PHPExcel读取Excel的数据和导出数据到Excel

    PHPExcel是一个PHP类库,用来帮助我们简单.高效实现从Excel读取Excel的数据和导出数据到Excel.也是我们日常开发中,经常会遇到的使用场景.比如有个客户信息表,要批量导出发给同事,我 ...

  3. phpexcel如何读取excel的数据和如何导出数据到excel

    phpexcel如何读取excel的数据和如何导出数据到excel 一.总结 一句话总结:去官网看参考手册和api,或者找中文的博客或者参考手册 1.phpexcel插件如何下载? 其实这些插件不仅可 ...

  4. 利用NPOI组件产Excel完整操作

    最终还是要使用NPOi了.刚开始做的是用com组件,发现如果本机不按照excel就不能使用,后来把其中一支改为了用Itextsharp产生pdf,但是还有几支批次要产生Excel,只能改用NPOI了. ...

  5. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  6. 上传读取Excel文件数据

    /// <summary> /// 上传读取Excel文件数据 /// 来自http://www.cnblogs.com/cielwater /// </summary> // ...

  7. js循环读取json数据,将读取到的数据用js写成表格

    ①js循环读取json数据的方式: var data=[{"uid":"2688","uname":"*江苏省南菁高级中学 022 ...

  8. java后台读取excel模板数据

    /** * 读取EXCEL模板数据 * * @param excelFilePath excel文件路径 * @param dataRowNum 开始读取数据的行数 * @param keyRowNu ...

  9. python读取excel所有数据(cmd界面)

    python读取excel所有数据(cmd界面) cmd界面显示excel数据 代码 import xlrd import os from prettytable import PrettyTable ...

随机推荐

  1. Java Native Interface Specification—Contents

    http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html 1. Introduction Java Nati ...

  2. INSTALL MYSQL IN MAC

    安装好MYSQL后,在System References中找到MYSQL,启动它. 启动之后在终端中输入添加MySQL路径的命令,把MYSQL路径添加到PATH中: PATH="$PATH& ...

  3. 浅谈html5网页内嵌视频

    更好的阅读体验:浅谈html5网页内嵌视频 如今在这个特殊的时代下:flash将死未死,微软和IE的历史问题,html5标准未定,苹果和谷歌的闭源和开源之争,移动互联网的大势所趋,浏览器各自为战... ...

  4. iOS 基础复习

    silverlight知识点:linqToSQL.视图.存储过程.索引.触发器 数据结构:数组.栈.队列.链表.属.图. 排序算法:插入.选择.交换(冒泡).归并 网络开发:HTTP短连接.socke ...

  5. Hadoop 2.4.1 设置问题小结【原创】

    先丢点问题小结到这里,免得忘记,有空再弄个详细教程玩,网上的教程要不就是旧版的,要不就是没说到点子上,随便搞搞也能碰上结果是对的时候,但是知其然而不知其所以然,没意思啊.解决问题的方法有很多种,总得找 ...

  6. Onmouseover被调用多次

    当一个容器,如div,不包含元素时.Onmouseover只执行一次,正常.当这个div包含其他子元素的时候,这个事件就被执行了多次,今天遇到了这个问题,特此记录下,解决方案. 这个是由于onmous ...

  7. 无线路由器WDS 桥接设置方法

    假设现在有a b c三台路由器,现在我们把b作为中心路由器,基本的配置之后使其能正常无线上网. 然后: 无线路由器A设置: 1.修改LAN口IP地址.在网络参数-LAN口设置中,修改IP地址和B路由器 ...

  8. Why is processing a sorted array faster than an unsorted array?

    这是我在逛 Stack Overflow 时遇见的一个高分问题:Why is processing a sorted array faster than an unsorted array?,我觉得这 ...

  9. Unit Of Work--工作单元(二)

    回顾 上一篇我们根据工作单元的原理基于ADO.NET进行了简单的实现,但是当项目需求发生变化的时候,比如需要引入ORM框架又要兼容当前ADO.NET实现的方式时,先前的实现就无法满足这个需求了. 话就 ...

  10. iis错误记录

    1:iis错误 解决方法: 输入C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis -i 这里由于我的是默认在Administ ...