找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2567|回复: 0

[分享] 用NPOI操作EXCEL--从Excel中抽取文本

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2015-1-27 09:54:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
http://www.cnblogs.com/atao/archive/2009/10/18/1585536.html
 我们知道,搜索引擎最擅长处理的就是文本,而Excel中的内容并不是以文本方式存储的。那么如果想要搜索引擎爬虫能够抓取到Excel中的内容是比较困难的,除非搜索引擎爬虫对Excel格式进行专门的处理。那么有没有办法解决此问题呢?有,通过NPOI将Excel内容文本化!
  如下,有这样一张Excel,如果想让它被搜索引擎收录,常用的方式是以HTML形式展现,但将一个个这样的Excel手工做成HTML页面显然比较麻烦。接下来,我们将提供一种方案,自动将Excel中的内容以HTML形式展现。
0.jpg
  其实基本思想也很简单,就是通过NPOI读取每个Cell中的内容,然后以HTML的形式输出。但要保证输出的HTML页面布局与Excel中的一致,还有点小技巧。下面是构造Table的代码:

  1. private HSSFSheet sht;
  2. protected String excelContent;

  3. protected void Page_Load(object sender, EventArgs e)
  4. {
  5.     HSSFWorkbook wb = new HSSFWorkbook(new FileStream(Server.MapPath("App_Data/quotation.xls"), FileMode.Open));
  6.     sht = wb.GetSheet("Sheet1");

  7.     //取行Excel的最大行数
  8.     int rowsCount = sht.PhysicalNumberOfRows;
  9.     //为保证Table布局与Excel一样,这里应该取所有行中的最大列数(需要遍历整个Sheet)。
  10.     //为少一交全Excel遍历,提高性能,我们可以人为把第0行的列数调整至所有行中的最大列数。
  11.     int colsCount = sht.GetRow(0).PhysicalNumberOfCells;

  12.     int colSpan;
  13.     int rowSpan;
  14.     bool isByRowMerged;

  15.     StringBuilder table = new StringBuilder(rowsCount * 32);

  16.     table.Append("<table border='1px'>");
  17.     for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++)
  18.     {
  19.         table.Append("<tr>");
  20.         for (int colIndex = 0; colIndex < colsCount; colIndex++)
  21.         {
  22.             GetTdMergedInfo(rowIndex, colIndex, out colSpan, out rowSpan, out isByRowMerged);
  23.             //如果已经被行合并包含进去了就不输出TD了。
  24.             //注意被合并的行或列不输出的处理方式不一样,见下面一处的注释说明了列合并后不输出TD的处理方式。
  25.             if (isByRowMerged)
  26.             {
  27.                 continue;
  28.             }

  29.             table.Append("<td");
  30.             if (colSpan > 1)
  31.                 table.Append(string.Format(" colSpan={0}", colSpan));
  32.             if (rowSpan > 1)
  33.                 table.Append(string.Format(" rowSpan={0}", rowSpan));
  34.             table.Append(">");

  35.             table.Append(sht.GetRow(rowIndex).GetCell(colIndex));

  36.             //列被合并之后此行将少输出colSpan-1个TD。
  37.             if (colSpan > 1)
  38.                 colIndex += colSpan - 1;

  39.             table.Append("</td>");

  40.         }
  41.         table.Append("</tr>");
  42.     }
  43.     table.Append("</table>");

  44.     this.excelContent = table.ToString();
  45. }
其中用到的GetTdMergedInfo方法代码如下:

  1. /// <summary>
  2. ///  获取Table某个TD合并的列数和行数等信息。与Excel中对应Cell的合并行数和列数一致。
  3. /// </summary>
  4. /// <param name="rowIndex">行号</param>
  5. /// <param name="colIndex">列号</param>
  6. /// <param name="colspan">TD中需要合并的行数</param>
  7. /// <param name="rowspan">TD中需要合并的列数</param>
  8. /// <param name="rowspan">此单元格是否被某个行合并包含在内。如果被包含在内,将不输出TD。</param>
  9. /// <returns></returns>
  10. private void GetTdMergedInfo(int rowIndex, int colIndex, out int colspan, out int rowspan, out bool isByRowMerged)
  11. {
  12.     colspan = 1;
  13.     rowspan = 1;
  14.     isByRowMerged = false;
  15.     int regionsCuont = sht.NumMergedRegions;
  16.     Region region;
  17.     for (int i = 0; i < regionsCuont; i++)
  18.     {
  19.         region = sht.GetMergedRegionAt(i);
  20.         if (region.RowFrom == rowIndex && region.ColumnFrom == colIndex)
  21.         {
  22.             colspan = region.ColumnTo - region.ColumnFrom + 1;
  23.             rowspan = region.RowTo - region.RowFrom + 1;

  24.             return;
  25.         }
  26.         else if (rowIndex > region.RowFrom && rowIndex <= region.RowTo && colIndex>=region.ColumnFrom && colIndex<=region.ColumnTo)
  27.         {
  28.             isByRowMerged = true;
  29.         }
  30.     }
  31. }
最后在apsx页面中输出构建好的Table:
<%=excelContent %>
执行效果如下:
1.jpg
我们发现,与Excel中的布局完全一样(这里没有处理单元格的样式,只处理了内容,有兴趣的读者也可以将Excel中单元格的样式也应用在HTML中)。这里为保证布局一致,主要是将Excel中的Region信息解析成Table的colSpan和rowSpan属性,如果对这两个属性不太了解,可以结合以下代码和示例加以了解:

  1. <table width="300px" border="1px">
  2. <tr>
  3.     <td colspan="2" rowspan="2">0,0</td>
  4.     <td>0,3</td>
  5. </tr>
  6. <tr>
  7.     <td>1,3</td>
  8. </tr>
  9. <tr>
  10.     <td rowspan="2">2,0</td>
  11.     <td colspan="2">2,1</td>
  12. </tr>
  13. <tr>
  14.     <td>3,1</td>
  15.     <td>3,2</td>
  16. </tr>
  17. </table>
复制代码
以上HTML代码对应的Table展现为:
2.jpg
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-17 22:35 , Processed in 0.185338 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表