admin管理员组文章数量:1627442
一、需求
在Autocad绘制多个矩形,获取矩形的名称跟长宽并通过代码把这些信息输出到EXECL文件中
二、准备
下面的笔记中将会用到libxl第三方库来进行EXECL文件的创建,所以需要提前下好libxl
libxl下载地址:LibXL download
libxl的使用需要付费,但是我们只是学习所以下面将会演示破解的使用(支持正版)
三、开发
1.配置项目库引用
右击项目>>属性
按照下图把libxl的相关目录引入进来
2.将libxl.dll丢进Autocad的安装目录,到这里libxl的配置就结束了
2.代码
添加类
代码如下:
Document.h:
#pragma once
class Document
{
public :
static void InitApp();
static void UnLoad();
public:
static wchar_t* Name;
static wchar_t* Key;
};
Document.cpp
#include "stdafx.h"
#include <dbmain.h>
#include <dbapserv.h>
#include <dbents.h>
#include <acdocman.h>
#include "libxl.h"
#include <sstream>
#include <iostream>
#include <string>
#include "Document.h"
#include "StdAfx.h"
#include <vector>
#include <fstream>
wchar_t* Document::Name = nullptr;
wchar_t* Document::Key = nullptr;
//定义一个矩形结构体
struct rectangle
{
ACHAR* Name;
double Length;
double Width;
};
void GenerateExcelDocument(std::vector<rectangle> rectangles);
// 获取 AutoCAD 中所有图形的属性
void GetAllEntities()
{
// 获取模型空间块表记录
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pModelSpace;
pBlockTable->getAt(ACDB_MODEL_SPACE, pModelSpace, AcDb::kForRead);
pBlockTable->close();
// 迭代模型空间中的所有实体
AcDbBlockTableRecordIterator *pIterator;
pModelSpace->newIterator(pIterator);
//定义一个矩形结构体数组
std::vector<rectangle> rectangles;
for (; !pIterator->done(); pIterator->step())
{
AcDbEntity *pEntity;
pIterator->getEntity(pEntity, AcDb::kForRead);
// 判断实体是否为多段线(长方形)
if (pEntity->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline *pPolyline = AcDbPolyline::cast(pEntity);
// 判断是否是闭合的多段线(长方形)
if (pPolyline->isClosed())
{
// 获取长方形的名称
ACHAR *name = pPolyline->layer();
// 计算长方形的长度和宽度
double length = 0.0;
double width = 0.0;
for (int i = 0; i < pPolyline->numVerts(); i++)
{
AcGePoint3d startPoint, endPoint;
pPolyline->getPointAt(i, startPoint);
pPolyline->getPointAt((i + 1) % pPolyline->numVerts(), endPoint); // Wrap around to the first point
double segmentLength = startPoint.distanceTo(endPoint);
if (segmentLength > length) {
length = segmentLength;
}
if (i == 0) {
width = segmentLength;
}
else {
if (segmentLength < width) {
width = segmentLength;
}
}
}
rectangle reg = {name,length,width};
rectangles.push_back(reg);
}
}
// 关闭对象
//pObj->close();
pEntity->close();
}
delete pIterator;
pModelSpace->close();
GenerateExcelDocument(rectangles);
}
void DeleteDocument(const std::string& filename) {
std::ifstream file(filename);
// 检查文件是否存在
if (file.good()) {
// 文件存在,删除文件
if (std::remove(filename.c_str()) == 0) {
std::cout << "File deleted successfully." << std::endl;
}
else {
std::cout << "Error deleting file." << std::endl;
}
}
//else {
// // 文件不存在,创建文件
// std::ofstream outfile(filename);
// if (outfile.is_open()) {
// std::cout << "File created successfully." << std::endl;
// outfile.close();
// }
// else {
// std::cout << "Error creating file." << std::endl;
// }
//}
}
//把char字符转换为wchar
wchar_t* CharConvertWChar(char* str) {
// 计算所需的宽字符长度(包括空字符结尾)
int nameSize = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
// 分配内存来存储宽字符
wchar_t* wideStr = new wchar_t[nameSize];
// 将多字节字符转换为宽字符
MultiByteToWideChar(CP_UTF8, 0, str, -1, wideStr, nameSize);
// 记得释放分配的内存
delete[] wideStr;
return wideStr;
}
void NameAndKeySetWchar() {
//libxl用户名
char* name = "QT";
//libxl注册key
char* key = "windows-2f2227060dcaef076cb96d6ca1m4n9hb";//这里就是破解后获取的key,直接用这个,如果不行的话可以评论,我再贴上破解文件的地址
Document::Name = CharConvertWChar(name);
Document::Key = CharConvertWChar(key);
}
// 生成 Excel 文件保存长方形的属性
void GenerateExcelDocument(std::vector<rectangle> rectangles)
{
NameAndKeySetWchar();
// 创建一个 Excel 工作簿对象
libxl::Book* book = xlCreateBook();
//使用注册码
book->setKey(Document::Name,Document::Key);
// 字体设置
libxl::Font* textFont = book->addFont();
textFont->setSize(8);
textFont->setName(L"Century Gothic");
// 格式设置
libxl::Format* textFormat = book->addFormat();
textFormat->setFont(textFont);
textFormat->setAlignH(libxl::ALIGNH_LEFT);
// 在工作簿中添加一个工作表
libxl::Sheet* sheet = book->addSheet(L"矩形明细信息");
// 设置工作表显示网格线
sheet->setDisplayGridlines(true);
//表格的行、列索引都从0开始
sheet->setCol(0,0,20, textFormat);
sheet->setCol(1,2,10, textFormat);
//给第一行设置行高
sheet->setRow(0,15);
//给表格第一行写入列名
sheet->writeStr(0,0,L"name");
sheet->writeStr(0, 1, L"length");
sheet->writeStr(0, 2, L"width");
//循环赋值给execl的单元格
for (int i = 1; i < rectangles.size() + 1; i++) {
sheet->setRow(i, 15);
rectangle reg = rectangles[i-1];
sheet->writeStr(i, 0, reg.Name, textFormat);
sheet->writeNum(i, 1, reg.Length, textFormat);
sheet->writeNum(i, 2, reg.Width, textFormat);
}
wchar_t* filename = L"D:\\VisualStudio2022WorkSpace\\ArxProject3\\receipt.xls";
std::string filename1 = "D:\\VisualStudio2022WorkSpace\\ArxProject3\\receipt.xls";
char* filename2 = "D:\\VisualStudio2022WorkSpace\\ArxProject3\\receipt.xls";
DeleteDocument(filename1);
book->save(filename);
book->release();
}
void Document::InitApp() {
acedRegCmds->addCommand(L"Document",L"OutDocument",L"OutDocument", ACRX_CMD_TRANSPARENT, GetAllEntities);
}
void Document::UnLoad() {
acedRegCmds->removeGroup(L"Document");
}
修改acrxEntryPoint.cpp,记得添加对Document头文件的引用
四、生成测试
1.生成解决方案
2.启动项目
3.Autocad使用命令appload加载生成的arx文件
4.绘制几个矩形
5.输入命令OUTDOCUMENT按下回车
6.打开生成的EXECL文件查看效果,一共绘制了四个矩形,所以EXECL中只记录了四个矩形的图层名称、长度、宽度信息
五、总结与思考
开发之前设想的需求是获取矩形的名称,但是在后续开发中发现绘制的矩形没有名称,他是一个多段线而组成的闭合多边形,所以我暂时理解为多段线是组成这种多边图形的基础单位,后续的开发中需要获取这种多边形的相关信息,可以通过多段线的属性或者再结合算法获取
版权声明:本文标题:AutoCAD ObjectArx获取矩形信息输出到EXECL文档 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728984279a1181859.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论