这几天上网时无意中看到这篇文章(利用java的开源组件JExcel创建无差异的Excel文件,并且导入到.net项目中去),看到评论里有人说有老外利用J#把JExcelAPI编译为.NET可用的组件了。当即下载下来测试,Excel文件读写竟然都正常ORZ。当然,不知这种方式编译出来的组件是否存在bug,但几天测试下来一般功能还是正常的。

下面说下这几天的测试情况:

1、在.net上使用需要依赖一个j#的库文件vjslib.dll,只要安装了j#的发行包,在以下目录就能找到这个组件C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

在VS下直接添加引用就可以了。(假如不想安装j#发行包,可下载我打包的几个必须的j#库文件,下载后放到网站的bin目录下就可以了)

2、修改单元格的值

);
sheet.addCell(cell);

// 覆盖原有单元格(保留格式)
WritableCell cell = sheet.getWritableCell(01);
jxl.format.CellFormat format 
= cell.getCellFormat();
if (format != null)
    cell 
= new jxl.write.Label(01"excel test", format);
else
    cell 
= new jxl.write.Label(01"excel test");
sheet.addCell(cell);

 

3、工作表区块复制

发现没有区块复制的功能,只能利用WritableCell的copyTo()函数自己实现了。不过这个函数只能复制单元格的内容和格式,像合并单元格范围和行的格式等都需要另外复制。下面是我写的复制区块的函数:


        /// 工作表内区块复制(不支持图片,图表等复杂对象复制)
        
/// </summary>
        
/// <param name="sheet">工作表</param>
        
/// <param name="srcCol">区块列索引</param>
        
/// <param name="srcRow">区块行索引</param>
        
/// <param name="srcWidth">区块的宽度</param>
        
/// <param name="srcHeight">区块的高度</param>
        
/// <param name="decCol">区块的目标列索引</param>
        
/// <param name="decRow">区块的目标行索引</param>
        private void CopyRange(WritableSheet sheet, int srcCol, int srcRow, int srcWidth, int srcHeight, int decCol, int decRow)
        {
            CopyCells(sheet, srcCol, srcRow, srcWidth, srcHeight, decCol, decRow);
            CopyMergeCells(sheet, srcCol, srcRow, srcWidth, srcHeight, decCol, decRow);
            CopyRowFormat(sheet, srcRow, srcHeight, decRow);
        }

        
private void CopyCells(WritableSheet sheet, int srcCol, int srcRow, int srcWidth, int srcHeight, int decCol, int decRow)
        {
            WritableCell newCell;
            WritableCell writeCell;
            Cell readCell;
            jxl.format.CellFormat readFormat;
            
for (int i = 0; i < srcHeight; i++)
            {
                
for (int j = 0; j < srcWidth; j++)
                {
                    readCell 
= sheet.getCell(srcCol + j, srcRow + i);
                    readFormat 
= readCell.getCellFormat();
                    
if (readCell.getType() == CellType.EMPTY && readFormat == null//没有格式的空单元格不处理
                        continue;
                    writeCell 
= sheet.getWritableCell(srcCol + j, srcRow + i);
                    newCell 
= writeCell.copyTo(srcCol + j + decCol, srcRow + i + decRow);

                    sheet.addCell(newCell);
                }
            }
        }

        
private void CopyRowFormat(WritableSheet sheet, int srcRow, int srcHeight, int decRow)
        {
            CellView cellView;
            
for (int i = 0; i < srcHeight; i++)
            {
                cellView 
= sheet.getRowView(srcRow + i);
                sheet.setRowView(decRow 
+ i, cellView);
            }
        }

        
private void CopyMergeCells(WritableSheet sheet, int srcCol, int srcRow, int srcWidth, int srcHeight, int decCol, int decRow)
        {
            Range[] ranges
= sheet.getMergedCells();  // 获取工作表现有单元格
            Cell brCell;  // 合并格的下对角单元格
            Cell ltCell;  // 合并格的上对角单元格
            int w1;  // 原区域的上对角到合并格上对角的水平距离
            int h1;  // 原区域的上对角到合并格上对角的垂直距离
            int w2;  // 合并格的宽度
            int h2;  // 合并格的高度
            for(int i=0; i<ranges.Length; i++)
            {
                
if (!IsInRange(ranges[i], srcCol, srcRow, srcWidth, srcHeight))
                    
continue;
                brCell 
= ranges[i].getBottomRight();
                ltCell 
= ranges[i].getTopLeft();
                w1 
= ltCell.getColumn() - srcCol;
                h1 
= ltCell.getRow() - srcRow;
                w2 
= brCell.getColumn() - ltCell.getColumn();
                h2 
= brCell.getRow() - ltCell.getRow();
                sheet.mergeCells(decCol 
+ w1, decRow + h1, decCol + w1 + w2, decRow + h1 + h2);
            }
        }

        
private bool IsInRange(Range merge, int srcCol, int srcRow, int srcWidth, int srcHeight)
        {
            
bool flag = true;

            
// 判断合并单元格上对角是否落在区块内
            Cell cell = merge.getTopLeft();
            
if (cell.getRow() < srcRow)
                flag 
= false;
            
if (cell.getColumn() < srcCol)
                flag 
= false;

            
// 判断合并单元格下对角是否落在区块内
            cell = merge.getBottomRight();
            
if (cell.getRow() > (srcRow + srcHeight))
                flag 
= false;
            
if (cell.getColumn() > (srcCol + srcWidth))
                flag 
= false;

            
return flag;
        }

 

4、下面是我写的一个demo,根据excel模板输出内容。只要在excel模板的单元格中写上格式内容:$数据库列名$,程序就会在指定单元格内写上数据库对应的数据。现在支持输出三种格式的报表:

1、数据表数据导出

NExcelAPI使用测试

2、分页导出数据

NExcelAPI使用测试

3、导出数据到一个sheet中

NExcelAPI使用测试

 

demo下载   J#库文件

相关文章:

  • 2021-12-30
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-03-06
  • 2021-06-27
  • 2022-03-01
  • 2021-09-14
  • 2022-02-17
  • 2021-08-22
相关资源
相似解决方案