您现在的位置是:首页>博客详情

NPOI 1.2教程 - 4 创建图形

FreshMan 2019年04月13日 23:44 NPOI,Excel,Office 219

简介之所有说NPOI强大,是因为常用的Excel操作她都可以通过编程的方式完成。这节开始,我们开始学习NPOI的画图功能。

2.4.1 用NPOI操作EXCEL--画线

之所有说NPOI强大,是因为常用的Excel操作她都可以通过编程的方式完成。这节开始,我们开始学习NPOI的画图功能。先从最简单的开始,画一条直线:

对应的代码为:

复制代码

HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch patriarch = sheet1.CreateDrawingPatriarch();
HSSFClientAnchor a1 = 
new HSSFClientAnchor(255125102315000,22);
HSSFSimpleShape line1 = patriarch.CreateSimpleShape(a1);

line1.ShapeType = HSSFSimpleShape.OBJECT_TYPE_LINE;
line1.LineStyle = HSSFShape.LINESTYLE_SOLID;
//在NPOI中线的宽度12700表示1pt,所以这里是0.5pt粗的线条。
line1.LineWidth = 6350;

复制代码

通常,利用NPOI画图主要有以下几个步骤:
1. 创建一个Patriarch;
2. 创建一个Anchor,以确定图形的位置;
3. 调用Patriarch创建图形;
4. 设置图形类型(直线,矩形,圆形等)及样式(颜色,粗细等)。

关于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的参数,有必要在这里说明一下:
dx1:起始单元格的x偏移量,如例子中的255表示直线起始位置距A1单元格左侧的距离;
dy1:起始单元格的y偏移量,如例子中的125表示直线起始位置距A1单元格上侧的距离;
dx2:终止单元格的x偏移量,如例子中的1023表示直线起始位置距C3单元格左侧的距离;
dy2:终止单元格的y偏移量,如例子中的150表示直线起始位置距C3单元格上侧的距离;
col1:起始单元格列序号,从0开始计算;
row1:起始单元格行序号,从0开始计算,如例子中col1=0,row1=0就表示起始单元格为A1;
col2:终止单元格列序号,从0开始计算;
row2:终止单元格行序号,从0开始计算,如例子中col2=2,row2=2就表示起始单元格为C3;

最后,关于LineStyle属性,有如下一些可选值,对应的效果分别如图所示:

 

2.4.2 用NPOI操作EXCEL--画矩形

上一节我们讲了NPOI中画图的基本步骤:
1. 创建一个Patriarch;
2. 创建一个Anchor,以确定图形的位置;
3. 调用Patriarch创建图形;
4. 设置图形类型(直线,矩形,圆形等)及样式(颜色,粗细等)。

这一节我们将按照这个步骤创建一个矩形。废话少说,上代码:

复制代码

HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch patriarch = sheet1.CreateDrawingPatriarch();
HSSFClientAnchor a1 = 
new HSSFClientAnchor(25512510231500022);
HSSFSimpleShape rec1 = patriarch.CreateSimpleShape(a1);
//此处设置图形类型为矩形
rec1.ShapeType = HSSFSimpleShape.OBJECT_TYPE_RECTANGLE;
//设置填充色
rec1.SetFillColor(125125125);
//设置边框样式
rec1.LineStyle = HSSFShape.LINESTYLE_DASHGEL;
//设置边框宽度
rec1.LineWidth = 25400;
//设置边框颜色
rec1.SetLineStyleColor(1000100);

复制代码

 

代码执行效果:
 
其中SetFillColor和SetLineStyleColor函数的三个参数分别是RGB三色值,具体表示什么颜色,找个Photoshop试试:)
关于HSSFClientAnchor参数说明、边框样式,边框宽度的说明可以参见前节。


2.4.3 用NPOI操作EXCEL--画圆形

前面我们学习了NPOI中的画简单直线和矩形的功能,今天我们一起学习一下它支持的另一种简单图形--圆形。同样,按照前面所讲的绘图“四步曲”:
1. 创建一个Patriarch;
2. 创建一个Anchor,以确定图形的位置;
3. 调用Patriarch创建图形;
4. 设置图形类型(直线,矩形,圆形等)及样式(颜色,粗细等)。
还是以例子加以说明:

复制代码

HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch patriarch = sheet1.CreateDrawingPatriarch();
HSSFClientAnchor a1 = 
new HSSFClientAnchor(00102300013);
HSSFSimpleShape rec1 = patriarch.CreateSimpleShape(a1);
rec1.ShapeType = HSSFSimpleShape.OBJECT_TYPE_OVAL;

rec1.SetFillColor(
125125125);
rec1.LineStyle = HSSFShape.LINESTYLE_DASHGEL;
rec1.LineWidth = 
12700;
rec1.SetLineStyleColor(
1000100);
WriteToFile();

复制代码


      这里rec1.ShapeType = HSSFSimpleShape.OBJECT_TYPE_OVAL;表示图形为椭圆。适当调整HSSFClientAnchor的各参数可以得到圆形。
      关于HSSFClientAnchor构造函数和边框、填充色等前两节都有介绍,这里不再重述。详情情见:画矩形画线

上面代码执行生成的Excel如下:

2.4.4 用NPOI操作EXCEL--画Grid

在NPOI中,本身没有画Grid的方法。但我们知道Grid其实就是由横线和竖线构成的,所在我们可以通过画线的方式来模拟画Grid。

 

复制代码

HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");

HSSFRow row = sheet1.CreateRow(
2);
row.CreateCell(
1);
row.HeightInPoints = 
240;
sheet1.SetColumnWidth(
29000);
int linesCount = 20;

HSSFPatriarch patriarch = sheet1.CreateDrawingPatriarch();
//因为HSSFClientAnchor中dx只能在0-1023之间,dy只能在0-255之间,所以这里采用比例的方式
double xRatio = 1023.0 / (linesCount*10);
double yRatio = 255.0 / (linesCount*10);

//画竖线
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 200;
for (int i = 0; i < linesCount; i++)
{
    HSSFClientAnchor a2 = 
new HSSFClientAnchor();
    a2.SetAnchor((
short)22, (int)(x1 * xRatio), (int)(y1 * yRatio),
            (
short)22, (int)(x2 * xRatio), (int)(y2 * yRatio));
    HSSFSimpleShape shape2 = patriarch.CreateSimpleShape(a2);
    shape2.ShapeType = (HSSFSimpleShape.OBJECT_TYPE_LINE);

    x1 += 
10;
    x2 += 
10;
}

//画横线
x1 = 0;
y1 = 
0;
x2 = 
200;
y2 = 
0;
for (int i = 0; i < linesCount; i++)
{
    HSSFClientAnchor a2 = 
new HSSFClientAnchor();
    a2.SetAnchor((
short)22, (int)(x1 * xRatio), (int)(y1 * yRatio),
            (
short)22, (int)(x2 * xRatio), (int)(y2 * yRatio));
    HSSFSimpleShape shape2 = patriarch.CreateSimpleShape(a2);
    shape2.ShapeType = (HSSFSimpleShape.OBJECT_TYPE_LINE);

    y1 += 
10;
    y2 += 
10;
}

复制代码

请注意HSSFClientAnchor对象中的dx只能取0-1023之间的数,dy只能取0-255之间的数。我们可以理解为是将单元格的宽和高平分成了1023和255份,设置dx和dy时相当于按比例取对应的座标。最终生成的Excel如下:


2.4.5 用NPOI操作EXCEL--插入图片

我们知道,在Excel中是可以插入图片的。操作菜单是“插入->图片”,然后选择要插入图片,可以很容易地在Excel插入图片。同样,在NPOI中,利用代码也可以实现同样的效果。在NPOI中插入图片的方法与画图的方法有点类似:

复制代码

//add picture data to this workbook.
byte[] bytes = System.IO.File.ReadAllBytes(@"D:\MyProject\NPOIDemo\ShapeImage\image1.jpg");
int pictureIdx = hssfworkbook.AddPicture(bytes, HSSFWorkbook.PICTURE_TYPE_JPEG);

//create sheet
HSSFSheet sheet = hssfworkbook.CreateSheet("Sheet1");

// Create the drawing patriarch.  This is the top level container for all shapes. 
HSSFPatriarch patriarch = sheet.CreateDrawingPatriarch();

//add a picture
HSSFClientAnchor anchor = new HSSFClientAnchor(00102300013);
HSSFPicture pict = patriarch.CreatePicture(anchor, pictureIdx);

复制代码

      与画简单图形不同的是,首先要将图片读入到byte数组,然后添加到workbook中;最后调用的是patriarch.CreatePicture(anchor, pictureIdx)方法显示图片,而不是patriarch.CreateSimpleShape(anchor)方法。上面这段代码执行后生成的Excel文件样式如下:


      我们发现,插入的图片被拉伸填充在HSSFClientAnchor指定的区域。有时可能我们并不需要拉伸的效果,怎么办呢?很简单,在最后加上这样一句用来自动调节图片大小:

pict.Resize();

添加代码后再执行上述代码,生成的Excel样式如下:

图片已经自动伸缩到原始大小了。


2.5 打印相关设置


打印设置主要包括方向设置、缩放、纸张设置、页边距等。NPOI 1.2支持大部分打印属性,能够让你轻松满足客户的打印需要。

首先是方向设置,Excel支持两种页面方向,即纵向和横向。

NPOI中如何设置呢?你可以通过HSSFSheet.PrintSetup.Landscape来设置,Landscape是布尔类型的,在英语中是横向的意思。如果Landscape等于true,则表示页面方向为横向;否则为纵向。

接着是缩放设置,

这里的缩放比例对应于HSSFSheet.PrintSetup.Scale,而页宽和页高分别对应于HSSFSheet.PrintSetup.FitWidthHSSFSheet.PrintSetup.FitHeight。要注意的是,这里的PrintSetup.Scale应该被设置为0-100之间的值,而不是小数。

接下来就是纸张设置了,对应于HSSFSheet.PrintSetup.PaperSize,但这里的PaperSize并不是随便设置的,而是由一些固定的值决定的,具体的值


纸张纸张
1US   Letter 8 1/2 x 11 in60A4   Plus 210 x 330 mm
2US Letter   Small 8 1/2 x 11 in61A5   Transverse 148 x 210 mm
3US   Tabloid 11 x 17 in62B5   (JIS) Transverse 182 x 257 mm
4US   Ledger 17 x 11 in63A3   Extra 322 x 445 mm
5US   Legal 8 1/2 x 14 in64A5   Extra 174 x 235 mm
6US   Statement 5 1/2 x 8 1/2 in65B5   (ISO) Extra 201 x 276 mm
7US   Executive 7 1/4 x 10 1/2 in66A2   420 x 594 mm
8A3   297 x 420 mm67A3   Transverse 297 x 420 mm
9A4   210 x 297 mm68A3   Extra Transverse 322 x 445 mm
10A4   Small 210 x 297 mm69Japanese   Double Postcard 200 x 148 mm
11A5   148 x 210 mm70A6   105 x 148 mm
12B4   (JIS) 250 x 35471Japanese   Envelope Kaku #2
13B5   (JIS) 182 x 257 mm72Japanese   Envelope Kaku #3
14Folio   8 1/2 x 13 in73Japanese   Envelope Chou #3
15Quarto   215 x 275 mm74Japanese   Envelope Chou #4
1610 x   14 in75Letter   Rotated 11 x 8 1/2 11 in
1711 x   17 in76A3   Rotated 420 x 297 mm
18US   Note 8 1/2 x 11 in77A4   Rotated 297 x 210 mm
19US   Envelope #9 3 7/8 x 8 7/878A5   Rotated 210 x 148 mm
20US   Envelope #10 4 1/8 x 9 1/279B4   (JIS) Rotated 364 x 257 mm
21US   Envelope #11 4 1/2 x 10 3/880B5   (JIS) Rotated 257 x 182 mm
22US   Envelope #12 4 \276 x 1181Japanese   Postcard Rotated 148 x 100 mm
23US   Envelope #14 5 x 11 1/282Double   Japanese Postcard Rotated 148 x 200 mm
24C   size sheet83A6   Rotated 148 x 105 mm
25D   size sheet84Japanese   Envelope Kaku #2 Rotated
26E   size sheet85Japanese   Envelope Kaku #3 Rotated
27Envelope   DL 110 x 220mm86Japanese   Envelope Chou #3 Rotated
28Envelope   C5 162 x 229 mm87Japanese   Envelope Chou #4 Rotated
29Envelope   C3 324 x 458 mm88B6   (JIS) 128 x 182 mm
30Envelope   C4 229 x 324 mm89B6   (JIS) Rotated 182 x 128 mm
31Envelope   C6 114 x 162 mm9012 x   11 in
32Envelope   C65 114 x 229 mm91Japanese   Envelope You #4
33Envelope   B4 250 x 353 mm92Japanese   Envelope You #4 Rotated
34Envelope   B5 176 x 250 mm93PRC   16K 146 x 215 mm
35Envelope   B6 176 x 125 mm94PRC   32K 97 x 151 mm
36Envelope   110 x 230 mm95PRC   32K(Big) 97 x 151 mm
37US   Envelope Monarch 3.875 x 7.5 in96PRC   Envelope #1 102 x 165 mm
386   3/4 US Envelope 3 5/8 x 6 1/2 in97PRC   Envelope #2 102 x 176 mm
39US   Std Fanfold 14 7/8 x 11 in98PRC   Envelope #3 125 x 176 mm
40German   Std Fanfold 8 1/2 x 12 in99PRC   Envelope #4 110 x 208 mm
41German   Legal Fanfold 8 1/2 x 13 in100PRC   Envelope #5 110 x 220 mm
42B4   (ISO) 250 x 353 mm101PRC   Envelope #6 120 x 230 mm
43Japanese   Postcard 100 x 148 mm102PRC   Envelope #7 160 x 230 mm
449 x   11 in103PRC   Envelope #8 120 x 309 mm
4510 x   11 in104PRC   Envelope #9 229 x 324 mm
4615 x   11 in105PRC   Envelope #10 324 x 458 mm
47Envelope   Invite 220 x 220 mm106PRC   16K Rotated
48RESERVED--DO   NOT USE107PRC   32K Rotated
49RESERVED--DO   NOT USE108PRC   32K(Big) Rotated
50US   Letter Extra 9 \275 x 12 in109PRC   Envelope #1 Rotated 165 x 102 mm
51US   Legal Extra 9 \275 x 15 in110PRC   Envelope #2 Rotated 176 x 102 mm
52US   Tabloid Extra 11.69 x 18 in111PRC   Envelope #3 Rotated 176 x 125 mm
53A4   Extra 9.27 x 12.69 in112PRC   Envelope #4 Rotated 208 x 110 mm
54Letter   Transverse 8 \275 x 11 in113PRC   Envelope #5 Rotated 220 x 110 mm
55A4   Transverse 210 x 297 mm114PRC   Envelope #6 Rotated 230 x 120 mm
56Letter   Extra Transverse 9\275 x 12 in115PRC   Envelope #7 Rotated 230 x 160 mm
57SuperA/SuperA/A4   227 x 356 mm116PRC   Envelope #8 Rotated 309 x 120 mm
58SuperB/SuperB/A3   305 x 487 mm117PRC   Envelope #9 Rotated 324 x 229 mm
59US   Letter Plus 8.5 x 12.69 in118PRC   Envelope #10 Rotated 458 x 324 mm

此表摘自《Excel Binary File Format (.xls) Structure Specification.pdf》)

HSSFSheet下面定义了一些xxxx_PAPERSIZE的常量,但都是非常常用的纸张大小,如果满足不了你的需要,可以根据上表自己给PaperSize属性赋值。所以,如果你要设置纸张大小可以用这样的代码:

HSSFSheet.PrintSetup.PaperSize=HSSFSheet.A4_PAPERSIZE;或HSSFSheet.PrintSetup.PaperSize=9;(A4 210*297mm)


再下来就是打印的起始页码,它对应于HSSFSheet.PrintSetup.PageStart和HSSFSheet.PrintSetup.UsePage,如果UsePage=false,那么就相当于“自动”,这时PageStart不起作用;如果UsePage=true,PageStart才会起作用。所以在设置PageStart之前,必须先把UsePage设置为true。

“打印”栏中的“网格线”设置对应于HSSFSheet.IsPrintGridlines,请注意,这里不是HSSFSheet.PrintSetup下面,所以别搞混了。这里之所以不隶属于PrintSetup是由底层存储该信息的record决定的,底层是把IsGridsPrinted放在GridsetRecord里面的,而不是PrintSetupRecord里面的,尽管界面上是放在一起的。另外还有一个HSSFSheet.IsGridsPrinted属性,这个属性对应于底层的gridset Record,但这个record是保留的,从微软的文档显示没有任何意义,所以这个属性请不要去设置。

“单色打印”则对应于HSSFSheet.PrintSetup.NoColors,这是布尔类型的,值为true时,表示单色打印。

“草稿品质”对应于HSSFSheet.PrintSetup.IsDraft,也是布尔类型的,值为true时,表示用草稿品质打印。

这里的打印顺序是由HSSFSheet.PrintSetup.LeftToRight决定的,它是布尔类型的,当为true时,则表示“先行后列”;如果是false,则表示“先列后行”。

在NPOI 1.2中,“行号列标”、“批注”和“错误单元格打印为”、“页边距”暂不支持,将在以后的版本中支持。

有关打印的范例可以参考NPOI 1.2正式版中的 SetPrintSettingsInXls项目。