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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using System.Data; namespace Utils
{
//http://www.cnblogs.com/luxiaoxun/p/3374992.html
public class ExcelDataTableConverter : IDisposable
{
private string fileName = null; //文件名
private IWorkbook workbook = null;
private FileStream fs = null;
private bool disposed; public ExcelDataTableConverter(string fileName)
{
this.fileName = fileName;
disposed = false;
} /// <summary>
/// 将DataTable数据导入到excel中
/// </summary>
/// <param name="data">要导入的数据</param>
/// <param name="isColumnWritten">DataTable的列名是否要导入</param>
/// <param name="sheetName">要导入的excel的sheet的名称</param>
/// <returns>导入数据行数(包含列名那一行)</returns>
public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten)
{
int i = 0;
int j = 0;
int count = 0;
ISheet sheet = null; fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook();
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(); try
{
if (workbook != null)
{
sheet = workbook.CreateSheet(sheetName);
}
else
{
return -1;
} if (isColumnWritten == true) //写入DataTable的列名
{
IRow row = sheet.CreateRow(0);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
}
count = 1;
}
else
{
count = 0;
} for (i = 0; i < data.Rows.Count; ++i)
{
IRow row = sheet.CreateRow(count);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
}
++count;
}
workbook.Write(fs); //写入到excel
return count;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return -1;
}
} /// <summary>
/// 将excel中的数据导入到DataTable中
/// </summary>
/// <param name="sheetName">excel工作薄sheet的名称</param>
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
/// <returns>返回的DataTable</returns>
public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
{
ISheet sheet = null;
DataTable data = new DataTable();
int startRow = 0;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs); if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数 if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
}
else
{
startRow = sheet.FirstRowNum;
} //最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null        DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
{
//dataRow[j] = row.GetCell(j).ToString(); //19890603会显示成MIDB(C2,7,6)
dataRow[j] = row.GetCell(j).StringCellValue;
}
}
data.Rows.Add(dataRow);
}
} return data;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
} public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (fs != null)
fs.Close();
} fs = null;
disposed = true;
}
}
}
}

调用:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPOI.XWPF.UserModel;
using NPOI.OpenXmlFormats.Wordprocessing;
using System.IO; namespace WordNPOI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} XWPFDocument doc = new XWPFDocument(); private void Form1_Load(object sender, EventArgs e)
{ } private void button1_Click(object sender, EventArgs e)
{
Utils.ExcelDataTableConverter edc = new Utils.ExcelDataTableConverter("60岁以上人员.xlsx");
DataTable dt = edc.ExcelToDataTable("sheet1", true); int rowCount = dt.Rows.Count;
int columnCount = dt.Columns.Count; //创建段落对象
XWPFParagraph p1 = doc.CreateParagraph();
//创建run对象
//本节提到的所有样式都是基于XWPFRun的,
//你可以把XWPFRun理解成一小段文字的描述对象,
//这也是Word文档的特征,即文本描述性文档。
//来自Tony Qu http://tonyqus.sinaapp.com/archives/609
XWPFRun r1 = p1.CreateRun();
r1.SetBold(true);
r1.SetText("数据导出demo");
r1.SetBold(true);
r1.FontFamily = "宋体";
r1.FontSize = 26;
//r1.SetFontFamily("Arial");//设置雅黑字体
//创建表格对象,行 列
XWPFTable table = doc.CreateTable(rowCount + 1, columnCount); //添加列头
for (int i = 0; i < columnCount; i++)
{
var ctt = table.GetRow(0).GetCell(i).GetCTTc();
var tcPr = ctt.AddNewTcPr();
tcPr.tcW = new CT_TblWidth();
tcPr.tcW.w = "6000";//单元格宽 单位是EMU,1英寸= 914400 EMU http://bbs.csdn.net/topics/390906055
tcPr.tcW.type = ST_TblWidth.dxa;
//table.SetColumnWidth(i, 5500); //无效果 特定数字5500又太大 貌似要设置为n*256 //设置单元格字体 样式 http://www.tuicool.com/articles/JFZzUj
var p = table.GetRow(0).GetCell(i).AddParagraph(); XWPFRun r = p.CreateRun();
r.FontFamily = "宋体";
r.FontSize = 10;
r.SetBold(true);
r.SetText(dt.Columns[i].ColumnName);
} for (int i = 1; i < rowCount; i++)
{
for (int j = 0; j < columnCount; j++)
{
string tem = dt.Rows[i][j].ToString();
table.GetRow(i).GetCell(j).SetText(dt.Rows[i][j].ToString());
}
} //插入图片
var gfs = new FileStream("1.png", FileMode.Open, FileAccess.Read);
var gp = doc.CreateParagraph();
gp.Alignment = ParagraphAlignment.CENTER; //居中
var gr = gp.CreateRun();
gr.AddPicture(gfs, (int)PictureType.JPEG, "1.png", 1000000, 1000000); //1000000 差不多100像素多一点
gfs.Close(); var gp1 = doc.CreateParagraph();
gp1.CreateRun().SetText("The End"); //bookmark书签 var items = doc.Paragraphs[0].Document.BodyElements; //CT_Bookmark b = new CT_Bookmark(); //CT_Bookmark ctBookmark = doc.Paragraphs[0].GetBookmarkStartArray(0); //foreach (CT_Bookmark bookmark in doc.Paragraphs[0].GetCTP().GetBookmarkStartList()) //网上的代码,发现找不到这个方法
//{
// Assert.AreEqual("poi", bookmark.name);
//} //书签0开始
int m_bookId = 0;//同一段内有多个书签,需要不同的Id,不同段的书签Id可以相同 CT_P m_p = doc.Document.body.AddNewP(); m_p.AddNewPPr().AddNewJc().val = ST_Jc.both; m_p.AddNewPPr().AddNewSpacing().line = "400";//固定行距20磅 m_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.exact; m_p.Items = new System.Collections.ArrayList(); CT_Bookmark m_ctbook1 = new CT_Bookmark(); m_bookId = m_p.Items.Count; m_ctbook1.id = m_bookId.ToString(); //"0"; m_ctbook1.name = "NPOI1";//书签名,超链接用 m_p.Items.Add(m_ctbook1); m_p.ItemsElementName = new List<ParagraphItemsChoiceType>(); m_p.ItemsElementName.Add(ParagraphItemsChoiceType.bookmarkStart); m_p.AddNewR().AddNewT().Value = "1、NPOI介绍"; //书签0结束 m_ctbook1 = new CT_Bookmark(); m_ctbook1.id = m_bookId.ToString();//"0"; m_p.Items.Add(m_ctbook1); m_p.ItemsElementName.Add(ParagraphItemsChoiceType.bookmarkEnd); //获得书签
int pcount = doc.Document.body.ItemsElementName.Count();
List<CT_Bookmark> bkList = new List<CT_Bookmark>();
for (int i = 0; i < pcount; i++)
{
var ctp = doc.Document.body.GetPArray(i);
if (ctp!=null)
{
var tempBookMarkList = ctp.GetBookmarkStartList();
bkList.AddRange(tempBookMarkList);
}
} foreach (var bookMark in bkList)
{//替换书签内容?????????????????找不到示例代码还是不支持此功能?
bookMark.colFirst = "1";
bookMark.colLast = "2";
bookMark.displacedByCustomXmlSpecified = true; MessageBox.Show(bookMark.name); } //保存文件到磁盘
FileStream out1 = new FileStream("simpleTable.docx", FileMode.OpenOrCreate);
doc.Write(out1);
out1.Close(); MessageBox.Show("done");
}
}
}

关于宽高设置:

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

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

    所需文件地址如下: http://pan.baidu.com/s/1nv0IHhn(ylk7)   1.下载微信开发工具0.7.0_x64 安装完成后,打开程序,进行微信扫码登录 2.下载微信开发工具 ...

  2. cocos2d ios 环境搭建

    一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...

  3. Untracked files不想add

    $ git status On branch feature/20160420_complain_630222 Untracked files: (use "git add <file ...

  4. 【Android学习】四种布局方式

    一.LinearLayout 线性布局,即一行展开或者一列展开,也可以嵌套,需要注意的属性如下: android:orentation  //对齐方式 二.FrameLayout 帧布局,即一层层叠起 ...

  5. IOS雕虫小技

    1,你所不知道的Mac截图的强大 2,抓包工具WireShark开发必备,需要装X11插件 3,Mac远程控制Windows桌面-CoRD.或者TeamViewer 4,Mac下解压缩BetterZi ...

  6. 哇塞,原来自己写 Google Chrome 浏览器扩展(插件)这么容易!

    1. 首先新建一个记事本,命名为 manifest.json,这是写 Google Chrome 浏览器扩展必须的文件 { "manifest_version": 2, " ...

  7. AssetBundle系列——打包前进行平台检测

    在生成AssetBundle的时候,如果目标平台和当前平台不一致,Unity3D会自动将当前平台转换为目标平台. 如果项目中资源量比较大,这个转换过程是相当漫长的,并且不能够强行中止. 所以最好在Bu ...

  8. 解决 ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)异常

    ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510) 解决方案: 在java_opts="-Xd ...

  9. 时尚前沿:15个创意的 3D 字体设计艺术作品欣赏

    在这里,我们为大家呈现30个创意的3D版式设计,注意每个设计中字体,颜色,款式的使用,让您享受并得到他们的灵感. 版式设计是一个美丽的艺术形式.无论是粗体还是细体,用不同的字体或使用拟物化技术操纵文本 ...

  10. js-条件语句、循环语句

    一. 常见条件语句 if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码 if...else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码 if... ...