CAD密码破解工具(CAD Password)是一款功能强大的CAD密码恢复工具。它能够对加密的cad图纸进行去除密码操作,软件能够支持cad系列全部版本,包括cad2013,2014最新版。只是暂时还不支持2015版
CAD Password软件特点
1、支持多种组合和密码字典。
2、能够修改字典攻击。
3、支持新的AutoCAD 2013文件格式。
4、支持多达32个同步处理线程(多CPU,多核心和HT)。
5、支持Unicode的密码。
CAD密码破解工具(CAD Password)是一款功能强大的CAD密码恢复工具。它能够对加密的cad图纸进行去除密码操作,软件能够支持cad系列全部版本,包括cad2013,2014最新版。只是暂时还不支持2015版
CAD Password软件特点
1、支持多种组合和密码字典。
2、能够修改字典攻击。
3、支持新的AutoCAD 2013文件格式。
4、支持多达32个同步处理线程(多CPU,多核心和HT)。
5、支持Unicode的密码。
插件下载:AutoCAD_Duotab_3.600(2006-2015)
插件名称:AutoCAD DuoTab
当前版本:3.6.0.0
功能:多标签管理插件
开发者:小胖工作室 LiteStudio
授权方式:完全免费,无广告
更新日期:2015.3.7
AutoCAD中界面最精美的多标签插件,与CAD完美融合,功能强大,拥有界面自定义功能。
支持版本AutoCAD2006-2015 32位和64位
3.600增加多文件批量打印功能,速度超快的批量打印,支持范围框选,指定图框块,智能自动识别图框。
支持外部插件,更灵活的功能扩展。
多图打印
插件商店
3.000标签滚动显示,再多文件也不怕
2.600带来悬浮菜单功能,最大化自定义设置,为不同的图元提供不同的快捷菜单
2.300版本 标签位置可以设置于工具栏下面了如果效果
有同学希望支持2014,2015。
经测试 for 2013版的完全可以支持 AutoCAD2014。
AutoCAD2015不完全支持,在关闭自带标签,设置经典标签位置选项的情况下可以满足正常使用。
需要注意的是,2014,2015版需要将插件所在位置添加为信任位置,并关闭自带的多标签
本插件经过XP+CAD2006,XP+CAD2007,XP+CAD2009,XP+CAD2010,Win7+2009,Win7+2012,Win7 64位+2010 32位,Win7 64位+2012 64位测试,2013版在Win7+2013,win7 64位+2013 64位,win7 64位+2014 64位,win7 64位+2015 64位中测试,在其他版本中有任何问题,希望大家在回复中具体指出
如果对你有用,别吝啬你的回复啊。
全面支持2006-2015 32位+64位!
安装使用:cad中使用Netload命令加载,插件将自动安装,升级直接覆盖原文件即可
更新日志:
2014/9/5 Version 3.000
1.现在当文件标签过多无法显示时可以用右键或中键拖动标签滚动显示。Ctrl + ← 滚动到开始,Ctrl + → 滚动到最后,Ctrl + ↓ 滚动到活动文件。
2.现在文件标签可以设置备注名
3.新增文件归类功能
4.改变了界面风格(内置原版本主题供切换)
5.修复了当鼠标移至 相关文件 按钮时,鼠标下移引起的菜单展开不完全的问题
6.现在收藏夹不再有20个数量的限制,并且多选文件可收藏为文件组
7.修复了当可移动磁盘不可用时,发送到菜单弹出设备未就绪的问题
8.现在可以直接拖动标签到收藏夹图标添加收藏
9.增加拖动标签排序的提示功能
10.当使用快捷键功能时,将处理Ctrl + tab 组合键,修正因标签排序造成的切换问题,按顺序切换
2014/5/31 Version 2.620
1.增加了lisp批处理功能
2.修复了卸载不能保存配置的bug
2014/5/5 Version 2.610
1.现在右击新建按钮将显示自定义模板列表,模板应位于插件目录下的AutoCAD DuoTab Template目录内,若要使用系统模板,请使用系统new命令
2014/4/20 Version 2.600
1.增加了浮动菜单功能
2.更新采用自动后台检查,但不会强制更新
2013/11/24 Version 2.300
1.现在标签可以显示在工具栏下面(绘图区域上面)了
2.整合了End-All剪贴板
3.Bug修复
2013/11/8 Version 2.010
1.增加及时脚本功能
2.标签右侧增加快速新建文件按钮
3.增加锁定选项,标签不显示关闭按钮
4.在标签空白处长按左键,显示最近关闭的文件
5.更新主题组件,使用*.dtheme主题文件
6.bug修复
2013/6/28 Version 1.971
1.增加发送文件到可移动磁盘的功能
2.增加AutoSweeper功能
3.界面微调
2013/4/24 Version 1.950
1.按下Alt键时提示文件编号
2.修复无法卸载的bug
3.点击右下角状态栏DuoTab进行配置管理
2013/3/31 Version 1.931
1.增加快捷键 Shift + Tab 切换布局
2.增加保存并关闭所有文件选项
3.快捷键优化,解决了快捷键冲突
4.现在直接拖动标签即可排序
5.增加配置加载管理,按需加载该插件
6.增加单文件不显示标签选项
7.修复了切换主题时的一个逻辑错误
这是一个为AutoCAD2000以上版本设计的单DWG多图纸的批量打印、批量生成布局、批量分图程序。程序根据自己判定的图框位置与尺寸,根据当前的打印机设置,自动调整打印的方式,实现批量打印、批量生成布局、批量分图。
AutoCAD Batchplot 批量打印程序 是一款免费软件。没有任何功能限制。然而,如果你喜欢它想让它继续的发展下去,不断的更新。您可以通过捐赠来支持软件的今后发展。
我的捐赠费用最低为 20 元,然而,如果愿意给我更多的支持,您可以捐助更多。
目前我只支持使用支付宝帐号捐赠。捐赠可登录支付宝网站,直接向支付宝帐号 arcqiufeng@163.com 付款。
支付宝的地址:https://www.alipay.com/
感谢您对我的支持!如果您对我作了捐赠,请同时用电子邮件通知我。我会在将来的版本的说明文档中添加捐赠人姓名。
感谢以下捐赠者:
vermin1986
usestone
李大坤
黄慧明
批量打印程序 v3.5.5
更新历史:

方法一:
1. 在AutoCAD安装目录找到c:\Program Files\AutoCAD 2006\Support\acad2006.lsp
用记事本打开,在最后加入(下段代码第二行即可,注意路径)
(if (not (=
(command “netload” “C:\\MXCAD\\bin\\Debug\\MXCAD.dll”)
;; Silent load.
(princ)
2. AutoCAD设置(重要,必须设置):
工具-选项-文件-支持文件搜索路径-添加-浏览到MXCAD路径
方法二:
修改注册表,新建记事本文件,重命名为netload.reg,加入以下内容,然后双击文件将信息添加到注册表即可。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R16.2\ACAD-4001:804\Applications\MXCAD]
“LOADER”=”C:\\MXCAD\\bin\\Debug\\MXCAD.dll”
“MANAGED”=dword:0001c101
“LOADCTRLS”=dword:0001c102″LOADCTRLS”:控制程序随CAD加载的方式,设为Ox02随CAD启动一起加载;
“LOADER”:告诉CAD所要加载的程序的路径;
“MANAGED”:设为Ox01,告诉CAD这是托管程序。
—————————–
附注:注册表键值”LOADCTRLS”控制说明,控制ARX程序的加载方式(上例中使用的是Ox02随CAD启动一起加载)
0x01:Load the application upon detection of proxy object.
当代理对像被控知时另载相应ARX程序.
0x02:Load the application upon AutoCAD startup.
当AutoCAD启动时加载相应ARX程序.
0x04:Load the application upon invocation of a command.
当输入命令时加载相应ARX程序.
0x08:Load the application upon request by the user or another application.
当有用户或别的程序请求时加载相应ARX程序.
0x10:Do not load the application.
从不加载该应用程序.
0x20:Load the application transparently.
显式加载该应该程序.(不知该项译法是否有误)
—————————–
打包时,将上述注册表项添加到注册表中,即可实现安装时自动配置。
主要找到以下类库:
MyXls(http://sourceforge.net/projects/myxls/)
Koogra(http://sourceforge.net/projects/koogra/)
ExcelLibrary(http://code.google.com/p/excellibrary/)
ExcelPackage(http://excelpackage.codeplex.com/)
EPPlus(http://epplus.codeplex.com/)
LinqToExcel(http://code.google.com/p/linqtoexcel/)
NetOffice(http://netoffice.codeplex.com/) 需安装Office Excel
从1-6的类库均不需要安装Office,不使用Office COM组件;而NetOffice需要安装Office,它提供的是与Office COM组件差不多的功能。
注:本文仅简单演示读取与创建Excel。
准备测试代码
首先,为这些类库准备一些测试代码,用于之后的测试。
aspx主要代码如下:
程序代码:aspx.cs主要代码如下:
程序代码:protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{//读取上传的文件绑定到GridView
GridView1.DataSource = ReadByXXX(FileUpload1.FileContent);
GridView1.DataBind();
}
}
protected void Button2_Click(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add(“aa“, typeof(string));
table.Columns.Add(“bb“, typeof(string));
table.Columns.Add(“cc“, typeof(string));
for (int i = 0; i < 10; i++)
{
string a = DateTime.Now.Ticks.ToString();
Thread.Sleep(1);
string b = DateTime.Now.Ticks.ToString();
Thread.Sleep(1);
string c = DateTime.Now.Ticks.ToString();
Thread.Sleep(1);
table.Rows.Add(a, b, c);
}
//从DataTable创建Excel并下载
RenderToBrowser(CreateByXXX(table), “test.xls“);
}
MyXls
MyXls支持Office Excel 97-2003格式(Biff8格式),但目前并不支持formula即公式;网上流传的支持2007是错误的说法。
使用它还需要注意的是,它与Office PIA一样,索引号是从1开始的。
另外不得不说的是,它的构造函数、Save方法、属性中的FileName让人看的眼花瞭乱,无所适从呐-_-。
主要使用的类型都位于org.in2bits.MyXls空间下,主要测试代码如下:
程序代码: int k = 2;
foreach (DataRow row in table.Rows)
{
for (int i = 1; i <= colCount; i++)
{
sheet.Cells.Add(k, i, row[i – 1]);
}
k++;
}
MemoryStream ms = new MemoryStream();
doc.Save(ms);
return ms;
}
DataTable ReadByMyXls(Stream xlsStream)
{
XlsDocument doc = new XlsDocument(xlsStream);
DataTable table = new DataTable();
Worksheet sheet = doc.Workbook.Worksheets[0];
int colCount = sheet.Rows[1].CellCount;
int rowCount = sheet.Rows.Count;
for (ushort j = 1; j <= colCount; j++)
{
table.Columns.Add(new DataColumn(sheet.Rows[1].GetCell(j).Value.ToString()));
}
for (ushort i = 2; i < rowCount; i++)
{
DataRow row = table.NewRow();
for (ushort j = 1; j <= colCount; j++)
{
row[j – 1] = sheet.Rows[i].GetCell(j).Value;
}
table.Rows.Add(row);
}
return table;
}
Koogra
Koogra支持Office 97-2003(Biff8)以及Office 2007以上(Xlsx)格式,但它仅提供读取功能,没有相关的创建Excel功能;另需要注意它的索引号又是从0开始的。
我在几台机器上测试不太稳定,即有的机器直接不能运行,没有深究什么问题。
操作xls格式的类型主要位于Net.SourceForge.Koogra.Excel空间,主要测试代码如下:
程序代码: Row headerRow = sheet.Rows[0];
uint colCount = headerRow.Cells.MaxCol;
uint rowCount = sheet.Rows.MaxRow;
Row tempr = null;
Cell tempc = null;
for (ushort j = 0; j <= colCount; j++)
{
tempc = headerRow.Cells[j];
if (tempc != null)
table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
}
for (ushort i = 0; i <= rowCount; i++)
{
DataRow row = table.NewRow();
tempr = sheet.Rows[i];
for (ushort j = 0; j <= colCount; j++)
{
tempc = tempr.Cells[j];
if (tempc != null)
row[j] = tempc.Value;
}
table.Rows.Add(row);
}
return table;
}
操作XLSX格式的类型主要位于Net.SourceForge.Koogra.Excel2007空间,主要测试代码如下:
程序代码: Row headerRow = sheet.GetRow(0);
uint colCount = sheet.CellMap.LastCol;
uint rowCount = sheet.CellMap.LastRow;
Row tempr = null;
ICell tempc = null;
for (ushort j = 0; j <= colCount; j++)
{
tempc = headerRow.GetCell(j);
if (tempc != null)
table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
}
for (ushort i = 0; i <= rowCount; i++)
{
DataRow row = table.NewRow();
tempr = sheet.GetRow(i);
for (ushort j = 0; j <= colCount; j++)
{
tempc = tempr.GetCell(j);
if (tempc != null)
row[j] = tempc.Value;
}
table.Rows.Add(row);
}
return table;
}
ExcelLibrary
听说这是国人开发的,目前支持97-2003(biff8)格式,未来可能会支持xlsx格式。它使用二维数组的方式来操作,这种方式比较接近Office PIA,另外,它的索引号是从0开始的。
在测试时,创建出的Excel有时内容是空的,可能存在bug。
它提供了一个DataSetHelper的工具类,用于从DataTable/DataSet和WorkBook之间的转换,但这个工具类不支持对流的操作,所以还是自己写测试代码(ExcelLibrary空间):
程序代码: int k = 1;
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < colCount; i++)
{
sheet.Cells[k, i] = new Cell(row[i]);
}
k++;
}
book.Worksheets.Add(sheet);
MemoryStream ms = new MemoryStream();
book.Save(ms);
return ms;
}
DataTable ReadByExcelLibrary(Stream xlsStream)
{
DataTable table = new DataTable();
Workbook book = Workbook.Load(xlsStream);
Worksheet sheet = book.Worksheets[0];
int colCount = sheet.Cells.LastColIndex;
int rowCount = sheet.Cells.LastRowIndex;
for (ushort j = 0; j <= colCount; j++)
{
table.Columns.Add(new DataColumn(sheet.Cells[0, j].StringValue));
}
for (ushort i = 1; i <= rowCount; i++)
{
DataRow row = table.NewRow();
for (ushort j = 0; j <= colCount; j++)
{
row[j] = sheet.Cells[i, j].Value;
}
table.Rows.Add(row);
}
return table;
}
ExcelPackage与EPPlus
ExcelPackage它主要支持OOXML即Office Open XML标准,Office 2007以上XLSX格式的读写;但它不支持对流的操作,仅支持对实体文件的操作。
EPPlus全称应该是ExcelPackage Plus,即ExcelPackage的增强版,它在ExcelPackage的基础上,增强了许多功能包括对流、Linq的支持,可以说相当不错。
它的索引号是从1开始的,主要使用的类型位于OfficeOpenXml空间,具体测试代码如下:
程序代码: int colCount = table.Columns.Count;
for (int i = 0; i < colCount; i++)
{
sheet.Cells[1, i + 1].Value = table.Columns[i].Caption;
}
int k = 2;
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < colCount; i++)
{
sheet.Cells[k, i + 1].Value = row[i];
}
k++;
}
MemoryStream ms = new MemoryStream();
package.SaveAs(ms);
return ms;
}
}
DataTable ReadByExcelLibrary(Stream xlsStream)
{
DataTable table = new DataTable();
using (ExcelPackage package = new ExcelPackage(xlsStream))
{
ExcelWorksheet sheet = package.Workbook.Worksheets[1];
int colCount = sheet.Dimension.End.Column;
int rowCount = sheet.Dimension.End.Row;
for (ushort j = 1; j <= colCount; j++)
{
table.Columns.Add(new DataColumn(sheet.Cells[1, j].Value.ToString()));
}
for (ushort i = 2; i <= rowCount; i++)
{
DataRow row = table.NewRow();
for (ushort j = 1; j <= colCount; j++)
{
row[j – 1] = sheet.Cells[i, j].Value;
}
table.Rows.Add(row);
}
}
return table;
}
LinqToExcel,NetOffice…
至于LinqToExcel,只能说是颗糖而已,不支持对流的操作,实在是无爱啊,不多说。
NetOffice提供与Office PIA相似的功能,又需要安装Office,实在不适合在web场景中使用,所以也不多说。
结尾
对于Excel 97-2003格式,还是用NPOI最好,API设计比较好(上面这些类库又是0又是1的索引号和二维数组实在让人好晕);而对于2007(xlsx)以上版本,可以使用EPPlus;这样基本所有的Excel格式通吃了。
以前的时候网站租用的西部数码的”虚拟主机”
其它的各方面都还挺满意,价钱也蛮实惠的。
但是就是有一点限制挺不好的,就是每月的流量有限制。
没办法很多东西都只能上传到百度云上
下载可能会有点麻烦。
现在好了,升级到了云主机,虽然价钱是贵了一些,但是还是值的。
为大家提供更好的服务,希望大家多多支持。
谢谢。
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明
本页地址:http://www.alongly.com/content/xlsresearch.html
第一章、XLS文件和十六进制
通常我们把EXCEL的文件格式叫做BIFF,即 Binary Interchange File Format的缩写,随着EXCEL的不断升级,其文件格式BIFF也在同步的更新与完善,因此对于不同版本的EXCEL有着不同的BIFF版本,下表对EXCEL目前最常用的版本和BIFF的部分版本进行了对照。
| EXCEL版本 | BIFF版本 |
| EXCEL 8.0(EXCEL 97) | BIFF8 |
| EXCEL 9.0(EXCEL 2000) | BIFF8 |
| EXCEL 10.0(EXCEL XP) | BIFF8x |
| EXCEL 11.0(EXCEL 2003) | BIFF8x |
其中BIFF8x为BIFF8的扩展版本,它在BIFF8的基础上改动了部分属性值。
在介绍XLS的文件结构时,大家需要知道关于XLS二进制文件的一些基本的结构内容知识:
1、 在文件数据的二进制存储中,低位8字节存放在地址的低位,高位8字节存放在地址的高位,因此在用十六进制编辑器来查看XLS文件时,对于一个完整的双字节,它的显示如 09 08,那么他的十六进制值应该为0x0809。
2、 XLS文件中的每条完整的数据是由一个标识、长度和数据内容来体现的,如某条数据显示 09 08 02 00 00 00,那么09 08代表这条完整数据的标识,02 00代表后面内容的长度,而00 00为实际的内容数据。
3、 在数据结构中,1个block的大小为512bytes,而XLS文件是由整数个block来组成的,因此其大小也均为512的倍数。
4、 XLS文件整体被分为多个子流(SubStream),这些SubStream都由若干个整数倍Block来组成的。
1、对于数据内容描述的表格,均采用如下样式
|
Offset |
Size |
Content |
其中
Offset(偏移量):该偏移量是指当前数据内容开始与该段数据内容区开始的偏移值。
Size(大小):该段数据内容区的大小
Content(内容):该段数据内容区的部分值或是说明
2、对于一段完整的数据区的描述方式为:
标识头+ 标识名称 + 标识说明+ 数据内容
XLS文件作为一个文件流(FileStream),是由多个子流(SubStream)构成的,以下的表格将XLS文件的各个SubStream按照顺序依次展现出来,其中包括了对XLS的各个SubStream的大小的说明,这样可以方便于大家对XLS文件格式有个总体的认识,同时我们由下面的各个Substream的大小可以看出,XLS文件的大小最少也为13,824 bytes。
| SubStream | 描述 |
| XLS Header区 | 占1 block (512 bytes),固定大小。 |
| WorkBook区 | 最小占8个block(4096 bytes) |
| Summary Information区 | 占8个block(4096 bytes),固定大小。 |
| Document Summary Information区 | 占8个block(4096 bytes),固定大小。 |
| BigBlock pointer区 | 占1个block(512 bytes),固定大小。 |
| RootEntry区 | 占1个block(512 byte s),固定大小。 |
其中WorkBook为数据变化区,它会随着文件内容的增大而增大,但始终保持Block的整数倍。
XLS文件的重要部位,如下表所示,其中所列位置和值对于生成XLS文件尤为重要。
|
Offset |
Size |
Content |
|
48 |
4 |
ROOT_START_BLOCK_POS,指向ROOT所在Block个数 |
|
76 |
4 |
BIG_BLOCK_DEPOT_BLOCKS_POS,指向BigBlock所在的Block个数 |
以下为WorkBook区的重要内容结构:
0x0809 Workbook Header,即BOF,长度范围1~20
|
Offset |
Size |
Content |
|
0 |
2 |
存放XLS文件的版本类型 BIFF8/ BIFF8X 0x0600 BIFF7 0x0500 |
|
2 |
2 |
WorkBook Globals,0x0005 |
0x0031 FONT,长度24bytes。
0x041E FORMAT
0x00E0 XF Extend FORMAT
0x0293 STYLE
0x0085 BOUNDSHEET,即Sheet指针区,N个Sheet则有N个0x0085,包含每个Sheet的名称、sheet数据内容在xls文件中的偏移量。
|
Offset |
Size |
Content |
|
0 |
4 |
该Sheet的BOF的绝对位移量,相对于Workbook |
0x008C Country ,语言和地区设置。
0x00FC SST内容(Sharing String Table 用来存放字符串,目的是为了让各个sheet都能够共享该SST中字符串内容)
|
Offset |
Size |
Content |
|
0 |
4 |
数据中所有字符串的数量 |
|
4 |
4 |
将要放在SST中字符串的数量 |
|
以下开始针对每个字符串进行循环处理 |
||
|
8 |
2 |
该字符串的长度,若为双字节字符也算做一个 |
|
10 |
1 |
字符串中若包含双字节字符(如中文),则为0x01,若为纯ASCII字符,则为0x00 |
|
11 |
n |
存放字符串信息 |
0x00FF Extended SST内容
在读取XLS文件时显得不重要,但当创建XLS文件时却非常重要
|
Offset |
Size |
Content |
|
0 |
2 |
每一区块字符串的个数,其值>=8 |
|
以下开始针对每一区块字符串进行循环处理 |
||
|
2 |
4 |
每一区块第一个字符的绝对位置 |
|
6 |
2 |
每一区块第一个字符的相对位置 |
|
8 |
2 |
保留 |
0x0809 Sheet1内容
0x0809 Header,20 bytes
0x020B Index,16+4*N个字节
|
Offset |
Size |
Content |
|
0 |
4 |
保留 |
|
4 |
4 |
第一行的序号 |
|
8 |
4 |
最后一行的序号(OpenOffice上介绍是sheet结尾的第一个未使用行的序号,行数的基数按0开始) |
|
10 |
4 |
指向DEFCOLWIDTH(0x0055)相对于Workbook Header的位置 |
|
14 |
4*N |
指向DBCELL(0x00D7)相对于Workbook Header的位置,当存在多个DBCELL时,需要设置多个。 N为该sheet的行数/32 |
0x0055 DEFCOLWIDTH,6 bytes
0x0200 Dimensions,18 byte,存放sheet1的行数和列数。
|
Offset |
Size |
Content |
|
0 |
4 |
第一行的序号 |
|
4 |
4 |
最后一行的序号 |
|
8 |
2 |
第一列的序号 |
|
10 |
2 |
最后一列的序号 |
|
12 |
2 |
保留 |
Row Block
0x0208 Row,20 bytes,Sheet中有多少行就有对应多少个0x0208开头的行信息,如果sheet中有5行,那么Row Block的大小就是20*5 bytes。
|
Offset |
Size |
Content |
|
0 |
2 |
行的序号 |
|
2 |
2 |
列的序号 |
Cell Block 设置sheet中每一个单元格的信息,顺序为针对每一行的每一列依次设置,如00, 01, 02 ……10, 11, 12 ……20, 21, 22……
0x00FD LABELSST,14bytes,针对字符串值已经在SST中保存,这里只保存其对应的序号。
0x027E RK2,14bytes,针对RK值(指编过码的整型或浮点型值)
0x00BD MULRK,28 bytes
0x00D7 DBCELL,随着行数的变化而发生变化。
|
Offset |
Size |
Content |
|
0 |
4 |
DBCELL的偏移量减去Row Block中第一个Row的偏移量 |
|
4 |
2 |
Cell Block中首行的第一个Cell的偏移量减去Row Block中第二个Row的偏移量 |
|
以下为循环处理部分,1<n<=Max_Row |
||
|
6 |
2 |
Cell Block中第n行的第一个Cell的偏移量减去第n-1行的第一个Cell的偏移量 |
当XLS中的行数大于32时,系统将循环处理,对于每个32行内容单独生成Row Block、Cell Block和DBCELL。
0x0809 Sheet2内容
0x0809 Sheet3内容 (如果有Sheet2、Sheet3)
0x000A EOF,Workbook结束标示符
属性,如作者,工作表类型等Excel中点击文件—〉属性的部分内容存放在此。
文档的属性,具体存放的内容大家可以研究研究。
每四个字节存放一个bigBlockChain。
文件结尾部分,其中对几个substream进行了描述,每个substream的描述占128个字节。
|
Offset |
Size |
Content |
|
0 |
128 |
存放文件中Root Entry属性 地址和大小 |
|
128 |
128 |
Workbook属性,地址和大小,占有实际数据的内容 |
|
256 |
128 |
SummaryInformation属性,地址和大小 |
|
384 |
128 |
DocumentSummaryInformation的属性,地址和大小 |
针对每个128字节内容,其偏移量116后的4个字节为每个区块的开始位置,之后的4个字节为每个区块的大小,地址和大小数据会随着内容量的变化而发生变化。
增加命名空间:
using System.Reflection;
代码:
public static class PrivateExtension
{
public static Object GetPrivateField(Object instance, String fieldname)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
while (field == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
field = type.GetField(fieldname, flag);
}
return field.GetValue(instance);
}
public static Object GetPrivateProperty(Object instance, String propertyname)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
PropertyInfo field = type.GetProperty(propertyname, flag);
while (field == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
field = type.GetProperty(propertyname, flag);
}
return field.GetValue(instance, null);
}
public static void SetPrivateField(Object instance, String fieldname, Object value)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
while (field == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
field = type.GetField(fieldname, flag);
}
field.SetValue(instance, value);
}
public static void SetPrivateProperty(Object instance, String propertyname, Object value)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
PropertyInfo field = type.GetProperty(propertyname, flag);
while (field == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
field = type.GetProperty(propertyname, flag);
}
field.SetValue(instance, value, null);
}
public static Object CallPrivateMethod(Object instance, String name, params Object[] param)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
MethodInfo method = type.GetMethod(name, flag);
while (method == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
method = type.GetMethod(name, flag);
}
return method.Invoke(instance, param);
}
public static Object CallPrivateMethodEx(Object instance, String name, params Object[] param)
{
if (param == null || param.Length == 0)
{
return CallPrivateMethod(instance, name, param);
}
Type[] types = new Type[param.Length];
for (int i = 0; i < param.Length; i++)
{
types[i] = param[i].GetType();
}
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
MethodInfo method = type.GetMethod(name, flag,null,types,null);
while (method == null && type.BaseType != null)
{
//访问基类,直到找到对应的字段或者属性或者方法
type = type.BaseType;
method = type.GetMethod(name, flag, null, types, null);
}
return method.Invoke(instance, param);
}
}
增加命名空间:
using NPOI.HSSF.UserModel;
using System.IO;
实现代码:
//文件名称
string fileName = “D:\\test.xls”;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
//读取文件
HSSFWorkbook book = new HSSFWorkbook(fs);
fs.Close();
FileStream fs1 = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
//写入文件
book.Write(fs1);
fs1.Close();
转载:http://tonyqus.sinaapp.com/archives/518
很多人并不知道Excel的页眉和页脚功能,因为在界面上是显示不了页眉和页脚的,必须在打印页面中才能看到,这也直接导致了其设置界面也显得更隐秘,你必须进入页面设置 –> 页眉和页脚才能设置。以下是Office 2007中的设置界面。
当你按“自定义页眉”或“自定义页脚”时,你会看到以下界面,Excel把页眉、页脚分成了左中右三部分,这一点绝非单纯体现在界面上,在底层的存储中也是如此。如果你设置的是“左”的内容,底层的存储字符串就会在开头加上&L,如果是“右”的内容则会加上&R,所以HeaderRecord中的字符串看上去是这样的:”&C&LFooter A&R”,这个字符串的意思是仅设置了“左”的内容,内容是Footer A。
看了这些我想你应该对页眉和页脚有所了解了,回过头来说NPOI,NPOI中主要是靠HSSFSheet.Header和HSSFSheet.Footer来设置的,这两个属性分别是HSSFHeader和HSSFFooter类型的。
参考代码如下:
|
1
2
3
4
5
6
7
8
|
HSSFSheet s1 = hssfworkbook.CreateSheet(<SPAN style="COLOR: #006080">"Sheet1"</SPAN>); s1.CreateRow(0).CreateCell(1).SetCellValue(123); <SPAN style="COLOR: #008000">//set header text</SPAN> s1.Header.Center = <SPAN style="COLOR: #006080">"This is a test sheet"</SPAN>; <SPAN style="COLOR: #008000">//set footer text</SPAN> s1.Footer.Left = <SPAN style="COLOR: #006080">"Copyright NPOI Team"</SPAN>; s1.Footer.Right = <SPAN style="COLOR: #006080">"created by Tony Qu(瞿杰)"</SPAN>; |
以上代码中我添加了页眉的Center内容,Footer的Left和Right内容,在打印预览中看到的效果大概是这样的:
页眉
页脚
至于一些Excel特殊字符,比如说页码可以用&P,当前日期可以用&D,其他的东西你就自己研究吧。
转载:http://tonyqus.sinaapp.com/archives/516
很多人不怎么用Excel中的批注,所以我特地截了张图,让大家知道本节我们要创建的到底是什么东西。
在过去,我们恐怕没有办法实现这一功能,因为无论是cvs法、html法、oledb法都没有提供这样的接口,当然Office PIA法可以做到,但是性能实在太差,而且稳定性不好,经常莫名其妙crash(这是某某兄弟给我的反馈,我引用了下,呵呵)。在以后的教程中,你将看到更多在过去无法通过传统方法实现的东西,好戏才刚刚开始。
批注主要有三个属性需要设置,一个是批注的位置和大小、一个是批注的文本、还有一个是批注的作者。
批注的位置和大小,在Excel中是与单元格密切相关的,NPOI中通过HSSFClientAnchor的实例来表示,它的构造函数比较复杂,有8个参数,它们分别是
|
参数 |
说明 |
| dx1 | 第1个单元格中x轴的偏移量 |
| dy1 | 第1个单元格中y轴的偏移量 |
| dx2 | 第2个单元格中x轴的偏移量 |
| dy2 | 第2个单元格中y轴的偏移量 |
| col1 | 第1个单元格的列号 |
| row1 | 第1个单元格的行号 |
| col2 | 第2个单元格的列号 |
| row2 | 第2个单元格的行号 |
例如,如果我们打算让注释显示在B3和E5之间,就应该这么写:
HSSFPatriarch patr = sheet.CreateDrawingPatriarch(); HSSFComment comment1 = patr.CreateComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 2 , 4, 4));
下面我们设置这个批注的内容和作者,这个比较简单:
comment1.String = new HSSFRichTextString("Hello World");
comment1.Author = "NPOI Team";
最后一步就是把批注赋给某个单元格:
HSSFCell cell = sheet.CreateRow(1).CreateCell(1); cell.CellComment = comment1;
对于批注,你有两种选择,一种是隐藏(默认),一种是显示(即表单一打开就显示该批注),可以通过comment1.Visible属性来控制。
看了上面这张图大家就应该明白了,这里有2个批注,下面那个是显示的,上面那个是隐藏的。
转载:http://tonyqus.sinaapp.com/archives/507
用过Excel的人都知道,单元格是Excel最有意义的东西,我们做任何操作恐怕都要和单元格打交道。在Excel中我们要添加一个单元格只需要点击任何一个单元格,然后输入内容就是了,但是Excel底层其实没有这么简单,不同的单元格是有不同的类型的,比如说数值单元格是用NumberRecord表示,文本单元格是用LabelSSTRecord表示,空单元格是用BlankRecord表示。这也就意味着,在设置单元格时,你必须告诉NPOI你需要创建哪种类型的单元格。
要创建单元格首先要创建单元格所在的行,比如,下面的代码创建了第0行:
|
1
2
|
HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1"); HSSFRow row1=sheet1.CreateRow(0); |
行建好了,就可以建单元格了,比如创建A1位置的单元格:
|
1
|
row1.CreateCell(0).SetCellValue(1); |
这里要说明一下,SetCellValue有好几种重载,你可以设置单元格为bool、double、DateTime、string和HSSFRichTextString类型。其中对于string类型的重载调用的就是HSSFRichTextString类型的重载,所以是一样的,HSSFRichTextString可用于有字体或者Unicode的文本。
如果你觉得每一行要声明一个HSSFRow很麻烦,可以用下面的方式:
|
1
|
sheet1.CreateRow(0).CreateCell(0).SetCellValue("This is a Sample"); |
这么用有个前提,那就是第0行还没创建过,否则得这么用:
|
1
|
sheet1.GetRow(0).CreateCell(0).SetCellValue("This is a Sample"); |
注意:这里的行在Excel里是从1开始的,但是NPOI内部是从0开始的;列在Excel里面是用字母表示的,而NPOI中也是用从0开始的数字表示的,所以要注意转换。
如果你要获得某一个已经创建的单元格对象,可以用下面的代码:
|
1
|
sheet1.GetRow(row_index).GetCell(column_index); |
前一节中我们讲解了如何创建一个新的Workbook,但在此过程中大家也许会发现一个细节,这些文件没有包括DocummentSummaryInformation和SummaryInformation头。如果你还不是很清楚我在说什么,可以看POIFS Browser打开test.xls文件后的截图:
你会发现只有Workbook目录,其他什么都没有,但事实上一个正常的xls文件,比如说Excel生成的xls文件是类似下面的结构:
是不是多出来DocumentSummaryInformation和SummaryInformation两个头?很多人可能对DocumentSummaryInformation和SummaryInformation很陌生,可能第一次听说这玩意,没事,这很正常,因为普通用户很少会去使用这些东西,但它们其实比想象中有用。
请看上图中的信息,如作者、标题、标记、备注、主题等信息,其实这些信息都是存储在DocummentSummaryInformation和SummaryInformation里面的,这么一说我想大家应该明白了吧,这些信息是为了快速提取文件信息准备。在Windows XP中,也有对应的查看和修改界面,只是没有Vista这么方便,如下所示:
这恐怕也是很多人对于这些信息漠不关心的原因吧,因为没有人愿意通过 右击文件->属性 这样复杂的操作去查看一些摘要信息。
提示
DocummentSummaryInformation和SummaryInformation并不是Office文件的专利,只要是OLE2格式,都可以拥有这两个头信息,主要目的就是为了在没有完整读取文件数据的情况下获得文件的摘要信息,同时也可用作桌面搜素的依据。要了解DocummentSummaryInformation的全部属性请见http://msdn.microsoft.com/en-us/library/aa380374(VS.85).aspx;要了解SummaryInformation的全部属性请见http://msdn.microsoft.com/en-us/library/aa369794(VS.85).aspx。
好了,说到这里,我想大家对于接下来我们要创建的内容有了初步的认识,下面我们就马上动手创建。
首先引用以下这些命名空间:
using NPOI.HSSF.UserModel; using NPOI.HPSF; using NPOI.POIFS.FileSystem;
其中与DocummentSummaryInformation和SummaryInformation密切相关的是HPSF命名空间。
首先创建Workbook
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
然后创建DocumentSummaryInformation
DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); dsi.Company = "NPOI Team";
再创建SummaryInformation
SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); si.Subject = "NPOI SDK Example";
因为是范例,这里仅各设置了一个属性,其他都没有设置。
现在我们把创建好的对象赋给Workbook,这样才能保证这些信息被写入文件。
hssfworkbook.DocumentSummaryInformation = dsi; hssfworkbook.SummaryInformation = si;
最后和2.1.1节一样,我们把Workbook通过FileStream写入文件。
转载:http://tonyqus.sinaapp.com/archives/501
创建Workbook说白了就是创建一个Excel文件,当然在NPOI中更准确的表示是在内存中创建一个Workbook对象流。
本节作为第2章的开篇章节,将做较为详细的讲解,以帮助NPOI的学习者更好的理解NPOI的组成和使用。
NPOI.HSSF是专门负责Excel BIFF格式的命名空间,供开发者使用的对象主要位于NPOI.HSSF.UserModel和NPOI.HSSF.Util命名空间下,下面我们要讲到的Workbook的创建用的就是NPOI.HSSF.UserModel.HSSFWorkbook类,这个类负责创建.xls文档。
在开始创建Workbook之前,我们先要在项目中引用一些必要的NPOI assembly,如下所示:
NPOI.dll
NPOI.POIFS.dll
NPOI.HSSF.dll
NPOI.Util.dll
要创建一个新的xls文件其实很简单,只要我们初始化一个新的HSSFWorkbook实例就行了,如下所示:
|
1
2
3
|
using NPOI.HSSF.UserModel; ... HSSFWorkbook hssfworkbook = new HSSFWorkbook(); |
是不是很方便啊,没有任何参数或设置,但这么创建有一些限制,这样创建出来的Workbook在Excel中打开是会报错的,因为Excel规定一个Workbook必须至少带1个Sheet,这也是为什么在Excel界面中,新建一个Workbook默认都会新建3个Sheet。所以必须加入下面的创建Sheet的代码才能保证生成的文件正常:
|
1
|
HSSFSheet sheet = hssfworkbook.CreateSheet("new sheet"); |
如果要创建标准的Excel文件,即拥有3个Sheet,可以用下面的代码:
|
1
2
3
|
hssfworkbook.CreateSheet("Sheet1"); hssfworkbook.CreateSheet("Sheet2"); hssfworkbook.CreateSheet("Sheet3"); |
最后就是把这个HSSFWorkbook实例写入文件了,代码也很简单,如下所示:
|
1
2
3
|
FileStream file = new FileStream("test.xls", FileMode.Create); hssfworkbook.Write(file); file.Close(); |
这里假设文件名是test.xls,,在创建完FileStream之后,直接调用HSSFWorkbook类的Write方法就可以了。
最后你可以打开test.xls文件确认一下,是不是有3个空的Sheet。
不需要Office就可以读写Excle的xls,xlsx等格式的文件,使用非常简单。
string fileName = “D:\\test.xls”;
Workbook book = new Workbook(fileName);
//一些操作
book.Save(fileName);//保存文件
下载:http://yun.baidu.com/share/link?shareid=1411549812&uk=721859502
转载:http://blog.csdn.net/yuandingmao/article/details/5563452
使用ResultBuffer类
在ObjectARX中,resbuf结构给AutoCAD专门数据提供了一个灵活的存储器。在托管API中,这个结构被映射在Autodesk.AutoCAD.DatabaseServices.ResultBuffer类中。
一个ResultBuffer类对象使用的方法与resbuf数据链相同。你要定义一个ResultBuffer并使它产生一系列的数据对。每一对数据由一个数据类型描述和一个值组成。在托管API中,
这些数据对是Autodesk.AutoCAD.DatabaseServices.TypedValue类的实例。这个类实现的功能与resbuf结构的restype和resval成员一样。
TypedValue.TypeCode属性是一个16位的整数值,它表示TypedValue.Value属性的数据类型。可以使用的TypeCode值取决于ResultBuffer实例的具体使用情况。
例如,适合于xrecord定义的TypeCode的值就不一定适用于xdata。Autodesk.AutoCAD.DatabaseServices.DxfCode枚举定义的代码精确地描述了所有可能的ResultBuffer数据类型的范围。
因为TypedValue.Value属性与System.Object的一个实例相对应,所以它可以包含任何数据类型。但是,Value数据必须与TypeCode所表示的类一致,以保证结果的可用性。
你可以通过给ResultBuffer的构造函数传递一个TypedValue对象数组来提前产生一个ResultBuffer,或者可以先构造一个空的ResultBuffer,
然后通过调用ResultBuffer.Add()方法来加入新的TypedValue对象。
#region 添加扩展数据XDATA
/// <summary>
/// 添加扩展数据xdata
/// </summary>
/// <param name=”ent”>被填充的实体</param>
/// <param name=”obj”>填充的数据</param>
/// <param name=”regapptablename”>regapptabl名称</param>
/// <returns></returns>
public Autodesk.AutoCAD.DatabaseServices.Entity AddXData(Autodesk.AutoCAD.DatabaseServices.Entity ent,Object obj,string regapptablename)
{
Autodesk.AutoCAD.DatabaseServices.ObjectId objId = ent.ObjectId;
Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices.WorkingDatabase;
Autodesk.AutoCAD.DatabaseServices.Entity retEntity ;
using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
{
retEntity = trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Entity;
Autodesk.AutoCAD.DatabaseServices.RegAppTable appTbl = trans.GetObject(db.RegAppTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.RegAppTable;
if (!appTbl.Has(regapptablename))
{
Autodesk.AutoCAD.DatabaseServices.RegAppTableRecord appTblRcd = new Autodesk.AutoCAD.DatabaseServices.RegAppTableRecord();
appTblRcd.Name = regapptablename;
appTbl.Add(appTblRcd);
trans.AddNewlyCreatedDBObject(appTblRcd, true);
}
Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = new Autodesk.AutoCAD.DatabaseServices.ResultBuffer();
// 先必须要将注册表添加到buffer里
resBuf.Add(new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.ExtendedDataRegAppName, regapptablename));
// 再将数据或对象加到buffer里 注意typecode 要是1000-1071里
resBuf.Add(new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.ExtendedDataAsciiString, obj));//将某个对象添加到扩展数据中
ent.XData = resBuf;
trans.Commit();
}
return retEntity;
}
#endregion
#region 获取扩展数据
/// <summary>
/// 获取扩展数据集合
/// </summary>
/// <param name=”ent”>实体</param>
/// <returns>返回System.Collections.IEnumerator</returns>
public System.Collections.IEnumerator GetXData(Autodesk.AutoCAD.DatabaseServices.Entity ent)
{
Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
System.Collections.IEnumerator itor;
Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
{
ent = (Autodesk.AutoCAD.DatabaseServices.Entity)trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = ent.XData;
if (resBuf != null)
{
//获取IEnumerator
itor = resBuf.GetEnumerator();
}
else
itor = null;
}
return itor;
}
/// <summary>
/// 获取实体的扩展数据
/// </summary>
/// <param name=”ent”>实体</param>
/// <returns>返回泛型的对象集</returns>
public List<System.Object> GetXDataList(Autodesk.AutoCAD.DatabaseServices.Entity ent)
{
Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
List<System.Object> objs = new List<System.Object>();
Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
{
ent = (Autodesk.AutoCAD.DatabaseServices.Entity)trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = ent.XData;
if (resBuf != null)
{
System.Collections.IEnumerator itor = resBuf.GetEnumerator();
while (itor.MoveNext())
{
Autodesk.AutoCAD.DatabaseServices.TypedValue tmpVal = (Autodesk.AutoCAD.DatabaseServices.TypedValue)itor.Current;
objs.Add(tmpVal.Value);
}
}
trans.Commit();
}
return objs;
}
#endregion
|
字符 |
说明 |
示例 |
输出 |
| C | 货币 | string.Format(“{0:C3}”, 2) | $2.000 |
| D | 十进制 | string.Format(“{0:D3}”, 2) | 002 |
| E | 科学计数法 | 1.20E+001 | 1.20E+001 |
| G | 常规 | string.Format(“{0:G}”, 2) | 2 |
| N | 用分号隔开的数字 | string.Format(“{0:N}”, 250000) | 250,000.00 |
| X | 十六进制 | string.Format(“{0:X000}”, 12) | C |
| string.Format(“{0:000.000}”, 12.2) | 012.200 |
There really isn’t any formatting within a strong, beyond it’s alignment. Alignment works for any argument being printed in a String.Format call.
| Sample | Generates |
| String.Format(“->{1,10}<-“, “Hello”); | -> Hello<- |
| String.Format(“->{1,-10}<-“, “Hello”); | ->Hello <- |
Basic number formatting specifiers:
| Specifier | Type | Format | Output (Passed Double 1.42) |
Output (Passed Int -12400) |
| c | Currency | {0:c} | $1.42 | -$12,400 |
| d | Decimal (Whole number) | {0:d} | System. FormatException |
-12400 |
| e | Scientific | {0:e} | 1.420000e+000 | -1.240000e+004 |
| f | Fixed point | {0:f} | 1.42 | -12400.00 |
| g | General | {0:g} | 1.42 | -12400 |
| n | Number with commas for thousands | {0:n} | 1.42 | -12,400 |
| r | Round trippable | {0:r} | 1.42 | System. FormatException |
| x | Hexadecimal | {0:x4} | System. FormatException |
cf90 |
Custom number formatting:
| Specifier | Type | Example | Output (Passed Double 1500.42) | Note |
| 0 | Zero placeholder | {0:00.0000} | 1500.4200 | Pads with zeroes. |
| # | Digit placeholder | {0:(#).##} | (1500).42 | |
| . | Decimal point | {0:0.0} | 1500.4 | |
| , | Thousand separator | {0:0,0} | 1,500 | Must be between two zeroes. |
| ,. | Number scaling | {0:0,.} | 2 | Comma adjacent to Period scales by 1000. |
| % | Percent | {0:0%} | 150042% | Multiplies by 100, adds % sign. |
| e | Exponent placeholder | {0:00e+0} | 15e+2 | Many exponent formats available. |
| ; | Group separator | see below |
The group separator is especially useful for formatting currency values which require that negative values be enclosed in parentheses. This currency formatting example at the bottom of this document makes it obvious:
Note that date formatting is especially dependant on the system’s regional settings; the example strings here are from my local locale.
| Specifier | Type | Example (Passed System.DateTime.Now) |
| d | Short date | 10/12/2002 |
| D | Long date | December 10, 2002 |
| t | Short time | 10:11 PM |
| T | Long time | 10:11:29 PM |
| f | Full date & time | December 10, 2002 10:11 PM |
| F | Full date & time (long) | December 10, 2002 10:11:29 PM |
| g | Default date & time | 10/12/2002 10:11 PM |
| G | Default date & time (long) | 10/12/2002 10:11:29 PM |
| M | Month day pattern | December 10 |
| r | RFC1123 date string | Tue, 10 Dec 2002 22:11:29 GMT |
| s | Sortable date string | 2002-12-10T22:11:29 |
| u | Universal sortable, local time | 2002-12-10 22:13:50Z |
| U | Universal sortable, GMT | December 11, 2002 3:13:50 AM |
| Y | Year month pattern | December, 2002 |
The ‘U’ specifier seems broken; that string certainly isn’t sortable.
Custom date formatting:
| Specifier | Type | Example | Example Output |
| dd | Day | {0:dd} | 10 |
| ddd | Day name | {0:ddd} | Tue |
| dddd | Full day name | {0:dddd} | Tuesday |
| f, ff, … | Second fractions | {0:fff} | 932 |
| gg, … | Era | {0:gg} | A.D. |
| hh | 2 digit hour | {0:hh} | 10 |
| HH | 2 digit hour, 24hr format | {0:HH} | 22 |
| mm | Minute 00-59 | {0:mm} | 38 |
| MM | Month 01-12 | {0:MM} | 12 |
| MMM | Month abbreviation | {0:MMM} | Dec |
| MMMM | Full month name | {0:MMMM} | December |
| ss | Seconds 00-59 | {0:ss} | 46 |
| tt | AM or PM | {0:tt} | PM |
| yy | Year, 2 digits | {0:yy} | 02 |
| yyyy | Year | {0:yyyy} | 2002 |
| zz | Timezone offset, 2 digits | {0:zz} | -05 |
| zzz | Full timezone offset | {0:zzz} | -05:00 |
| : | Separator | {0:hh:mm:ss} | 10:43:20 |
| / | Separator | {0:dd/MM/yyyy} | 10/12/2002 |
| Specifier | Type |
| g | Default (Flag names if available, otherwise decimal) |
| f | Flags always |
| d | Integer always |
| x | Eight digit hex. |
String.Format(“{0:$#,##0.00;($#,##0.00);Zero}”, value);
This will output “$1,240.00” if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string “Zero” if the number is zero.
String.Format(“{0:(###) ###-####}”, 18005551212);
This will output “(800) 555-1212”.
变量.ToString()
字符型转换 转为字符串
12345.ToString(“n”); //生成 12,345.00
12345.ToString(“C”); //生成 ¥12,345.00
12345.ToString(“e”); //生成 1.234500e+004
12345.ToString(“f4”); //生成 12345.0000
12345.ToString(“x”); //生成 3039 (16进制)
12345.ToString(“p”); //生成 1,234,500.00%
上一篇文章介绍了如何定义一个Jig
这里我们来使用它。
DrawJigEnt jig = new DrawJigEnt(ents);
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
PromptResult pr = ed.Drag(jig);
和C++里面不同,这里是通过Editor类来调用的。
转载:http://www.cnblogs.com/wangyong/archive/2010/01/20/1652412.html
在CAD的二次开发中,有时会使用JIG技术来实现操作的动态性、交互,最常见的比如说是在CAD中定制自己的移动和复制,当然要保持CAD中原有的动态显示效果。
在JIG中我们可以继承EntityJig和DrawJig,对于这两个类,那这两个类有什么区别呢?他们的使用场合又有什么区别呢?
其实,他们之间在操作一些简单的实体的时候是没有多大区别的,硬要说区别的话,那就是在实现一个相同功能时DrawJig比EntityJig的代码简单一些。(注意:是指在操作简单的实体的时候,比如实体的数量就一个)。
EntityJig:一般用于图元实体的拖动,要求先生成实体Entity
protected override bool Update()
{
throw new NotImplementedException();
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
throw new NotImplementedException();
}
DrawJig:一般用于复杂图形的拖动
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
throw new NotImplementedException();
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
throw new NotImplementedException();
}
在拖动一个实体的时候,不管是用EntityJig还是DrawJig效果都一样,但是当我们在处理多个实体的移动,我们要求鼠标可以实时动态显示要拖动的多个实体,这点,EntityJig却无法实现了,但如果是DrawJig却很容易实现。
而且对于动态生成实体(比如指定一个圆心,动态生成一个圆),用DrawJig中的WorlDraw可以灵活控制实现生成。
相比之下,是不是发现DrawJig优胜于EntityJig(个人理解
).
下面贴出上图实现的代码:
代码
#region DrawJig动态拖动多个实体
public class DrawJigEnt : DrawJig
{
//变量
Point3d oldPt;//实体移动之前的位置
Point3d newPt;//实体移动之后的位置
Vector3d v;//实体移动的向量
List<Entity> ents = new List<Entity>();
List<Point3d> oldPts = new List<Point3d>();
public DrawJigEnt(List<Entity> ents)
{
oldPt = Point3d.Origin;
newPt = Point3d.Origin;
v = new Vector3d();
this.ents = ents;
Autodesk.AutoCAD.DatabaseServices.Entity ent = ents[0];
if (ent is BlockReference)
{
BlockReference br = ent as BlockReference;
oldPt = br.Position;
}
for (int i = 1; i < ents.Count; i++)
{
if (ents[i] is BlockReference)
{
BlockReference br = ents[i] as BlockReference;
oldPts.Add(br.Position);
}
}
}
//更新
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
Entity ent = ents[0];
ent.UpgradeOpen();
if (ent is BlockReference)
{
BlockReference br = ent as BlockReference;
br.Position = newPt;
draw.Geometry.Draw(br);
}
v = newPt.GetVectorTo(oldPt);
for(int i =1;i<ents.Count;i++)
{
Entity entity = ents[i];
entity.UpgradeOpen();
if (entity is BlockReference)
{
BlockReference br = entity as BlockReference;
br.Position = oldPts[i – 1] + v;
draw.Geometry.Draw(entity);
}
}
return true;
}
//取样函数
protected override SamplerStatus Sampler(JigPrompts prompts)
{
JigPromptOptions opt = new JigPromptOptions();
opt.UserInputControls = UserInputControls.Accept3dCoordinates | UserInputControls.NoNegativeResponseAccepted | UserInputControls.NullResponseAccepted;
opt.UseBasePoint = true;
opt.Cursor = CursorType.RubberBand;
opt.BasePoint = oldPt;
opt.Message = “选择移动到的终点”;
PromptPointResult res = prompts.AcquirePoint(opt);
if (PromptStatus.OK == res.Status)
{
if (res.Value == newPt)
{
return SamplerStatus.NoChange;
}
newPt = res.Value;
}
else
{
return SamplerStatus.Cancel;
}
return SamplerStatus.OK;
}
}
#endregion