求助妖哥啊,关于dbgrid导入excel问题

123456jiihi 2015-03-31 09:56:47
看了妖哥在网站的dbgrid导出excel的函数,拿来用,编译没问题,但是一点按钮导出excel就会提示“”不正确的变量类型“”,我断点调试发现是设置Excel文档的字体这地方有问题,于是我就把这段注释掉,再编译运行,会报错(不能设置类Range的ColumnWidth属性),由于本人新学CB对于OLE完全不懂,所以想请妖哥帮帮忙 看看这个怎么改下。我用的是xe7.by the way 我在头文件已经添加这个函数了

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DBGrid2Excel(TDBGrid *dbg, String strXlsFile)
{
if(!dbg->DataSource->DataSet->Active) // 数据集没有打开就返回
return;
Variant vExcelApp, vSheet;
try
{
vExcelApp = Variant::CreateObject("Excel.Application");
}
catch(...)
{
MessageBox(0, L"启动 Excel 出错, 可能是没有安装Excel.",
L"DBGrid2Excel", MB_OK);
return;
}
// 隐藏Excel界面
vExcelApp.OlePropertySet("Visible", false);
// 新建一个工作表
vExcelApp.OlePropertyGet("Workbooks").OleFunction("Add", 1); // 工作表
// 操作这个工作表
vSheet = vExcelApp.OlePropertyGet("ActiveWorkbook")
.OlePropertyGet("Sheets", 1);
设置Excel文档的字体
vSheet.OleProcedure("Select");
vSheet.OlePropertyGet("Cells").OleProcedure("Select");
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("Size", dbg->Font->Size);
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("Name", dbg->Font->Name.c_str());
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("FontStyle", "常规");
vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select");
// 表格的行数
int nRowCount(dbg->DataSource->DataSet->RecordCount + 1);
nRowCount = nRowCount < 2? 2: nRowCount;
// 表格的列数
int nColCount(dbg->Columns->Count);
nColCount = nColCount < 1? 1: nColCount;
//设置单元格的宽度
for(int i=0; i<nColCount; i++)
{
int nColWidth = dbg->Columns->Items[i]->Width;
vExcelApp.OlePropertyGet("Columns", i + 1)
.OlePropertySet("ColumnWidth", nColWidth / 7);
}
//----------------------------------------------------------------------------
// 抱歉,这个提示又来了,为了防止不负责任的转载者,只好在此留些信息。
// 作者:ccrun(老妖) info@ccrun.com
// 本文转自 C++Builder 研究 - http://www.ccrun.com/article/go.asp?i=635&d=g75jbn
//----------------------------------------------------------------------------
// 先将列名写入Excel表格
for(int j=0; j<dbg->Columns->Count; j++)
{
// 标题行的行高
vExcelApp.OlePropertyGet("Rows", 1).OlePropertySet("RowHeight", 20);
//
vSheet.OlePropertyGet("Cells", 1, j + 1)
.OlePropertySet("Value",
dbg->Columns->Items[j]->FieldName.c_str());
// 设置列名单元格的背景色
Variant vInter = vSheet.OlePropertyGet(
"Cells", 1, j + 1).OlePropertyGet("Interior");
vInter.OlePropertySet("ColorIndex", 15); // 灰色
vInter.OlePropertySet("Pattern", 1); // xlSolid
vInter.OlePropertySet("PatternColorIndex", -4105); // xlAutomatic
}
// 将DBGrid中的数据写入Excel表格
dbg->DataSource->DataSet->First();
for(int i=0; i<nRowCount; i++)
{
// 普通数据行的行高16
vExcelApp.OlePropertyGet("Rows", i + 2).OlePropertySet("RowHeight", 16);
// 63 63 72 75 6E 2E 63 6F 6D
for(int j=0; j<dbg->Columns->Count; j++)
{
vSheet.OlePropertyGet("Cells", i + 2, j + 1)
.OlePropertySet("Value",
dbg->DataSource->DataSet->FieldByName(
dbg->Columns->Items[j]->FieldName)->AsString.c_str());
}
dbg->DataSource->DataSet->Next();
}
// 保存Excel文档并退出
vExcelApp.OlePropertyGet("ActiveWorkbook")
.OleFunction("SaveAs", strXlsFile.c_str());
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
// 工作结束
MessageBox(0, L"DBGrid2Excel 转换结束!",
L"DBGrid2Excel", MB_OK);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{

ADOQuery2->Clone(ADOQuery1);
ADOQuery2->Open();

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DBGrid2Excel(DBGrid1,"C:\\Users\\Administrator\\Desktop\\123.xlsx");
}
//---------------------------------------------------------------------------


...全文
223 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
宝龙哥 2015-04-01
  • 打赏
  • 举报
回复
你有按照我说的改吗?先打开数据集,如果是Windows7的话必须选获得"C:\\Users\\Administrator\\Desktop\\123.xlsx"的写权限,然后把函数里面的代码改成:
    if(!dbg->DataSource->DataSet->Active) // 数据集没有打开就返回
        return;
    Variant vExcelApp, vSheet;
    try
    {
		vExcelApp = Variant::CreateObject( (WideString)L"Excel.Application");
    }
    catch(...)
    {
        MessageBox(0, L"启动 Excel 出错, 可能是没有安装Excel.",
                L"DBGrid2Excel", MB_OK);
        return;
    }
    // 隐藏Excel界面
    vExcelApp.OlePropertySet( (WideString)L"Visible", false);
    // 新建一个工作表
    vExcelApp.OlePropertyGet( (WideString)L"Workbooks").OleFunction( (WideString)L"Add", 1); // 工作表
    // 操作这个工作表
    vSheet = vExcelApp.OlePropertyGet( (WideString)L"ActiveWorkbook")
            .OlePropertyGet( (WideString)L"Sheets", 1);
    // 设置Excel文档的字体
    vSheet.OleProcedure( (WideString)L"Select");
    vSheet.OlePropertyGet( (WideString)L"Cells").OleProcedure( (WideString)L"Select");
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"Size", dbg->Font->Size);
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"Name", dbg->Font->Name.c_str());
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"FontStyle", (WideString)L"常规");
    vSheet.OlePropertyGet( (WideString)L"Cells", 1, 1).OleProcedure( (WideString)L"Select");
    // 表格的行数
    int nRowCount(dbg->DataSource->DataSet->RecordCount + 1);
    nRowCount = nRowCount < 2? 2: nRowCount;
    // 表格的列数
    int nColCount(dbg->Columns->Count);
    nColCount = nColCount < 1? 1: nColCount;
    //设置单元格的宽度
    for(int i=0; i<nColCount; i++)
    {
        int nColWidth = dbg->Columns->Items[i]->Width;
        vExcelApp.OlePropertyGet( (WideString)L"Columns", i + 1)
                .OlePropertySet( (WideString)L"ColumnWidth", nColWidth / 7);
    }

    // 先将列名写入Excel表格
    for(int j=0; j<dbg->Columns->Count; j++)
    {
        // 标题行的行高
        vExcelApp.OlePropertyGet( (WideString)L"Rows", 1).OlePropertySet( (WideString)L"RowHeight", 20);
        //
        vSheet.OlePropertyGet( (WideString)L"Cells", 1, j + 1)
                .OlePropertySet( (WideString)L"Value",
                dbg->Columns->Items[j]->FieldName.c_str());
        // 设置列名单元格的背景色
        Variant vInter = vSheet.OlePropertyGet(
                "Cells", 1, j + 1).OlePropertyGet( (WideString)L"Interior");
        vInter.OlePropertySet( (WideString)L"ColorIndex", 15); // 灰色
        vInter.OlePropertySet( (WideString)L"Pattern", 1); // xlSolid
        vInter.OlePropertySet( (WideString)L"PatternColorIndex", -4105); // xlAutomatic
	}
    // 将DBGrid中的数据写入Excel表格
    dbg->DataSource->DataSet->First();
    for(int i=0; i<nRowCount; i++)
    {
        // 普通数据行的行高16
        vExcelApp.OlePropertyGet( (WideString)L"Rows", i + 2).OlePropertySet( (WideString)L"RowHeight", 16);
        // 63 63 72 75 6E 2E 63 6F 6D
        for(int j=0; j<dbg->Columns->Count; j++)
        {
            vSheet.OlePropertyGet( (WideString)L"Cells", i + 2, j + 1)
                .OlePropertySet( (WideString)L"Value",
				(WideString)dbg->DataSource->DataSet->FieldByName(
                dbg->Columns->Items[j]->FieldName)->AsString);
        }
        dbg->DataSource->DataSet->Next();
	}

    // 保存Excel文档并退出
    vExcelApp.OlePropertyGet( (WideString)L"ActiveWorkbook")
			.OleFunction( (WideString)L"SaveAs", (WideString)strXlsFile);
    vExcelApp.OleFunction( (WideString)L"Quit");
    vSheet = Unassigned;
    vExcelApp = Unassigned;
    // 工作结束
    MessageBox(0, L"DBGrid2Excel 转换结束!",
            L"DBGrid2Excel", MB_OK);
123456jiihi 2015-04-01
  • 打赏
  • 举报
回复
OK解决了 非常感谢kfrght
宝龙哥 2015-04-01
  • 打赏
  • 举报
回复
嘎的,是我疏忽了,还有两个.c_str()没有被替换成widestring,找到它们,按照我教你的方法替换
flame1122 2015-04-01
  • 打赏
  • 举报
回复
我觉得应该是 //设置单元格的宽度 for(int i=0; i<nColCount; i++) { int nColWidth = dbg->Columns->Items[i]->Width; vExcelApp.OlePropertyGet( (WideString)L"Columns", i + 1) .OlePropertySet( (WideString)L"ColumnWidth", nColWidth / 7); } 这个的问题 建议修改一下
123456jiihi 2015-04-01
  • 打赏
  • 举报
回复
引用 5 楼 kfrght 的回复:
你有按照我说的改吗?先打开数据集,如果是Windows7的话必须选获得"C:\\Users\\Administrator\\Desktop\\123.xlsx"的写权限,然后把函数里面的代码改成:
    if(!dbg->DataSource->DataSet->Active) // 数据集没有打开就返回
        return;
    Variant vExcelApp, vSheet;
    try
    {
		vExcelApp = Variant::CreateObject( (WideString)L"Excel.Application");
    }
    catch(...)
    {
        MessageBox(0, L"启动 Excel 出错, 可能是没有安装Excel.",
                L"DBGrid2Excel", MB_OK);
        return;
    }
    // 隐藏Excel界面
    vExcelApp.OlePropertySet( (WideString)L"Visible", false);
    // 新建一个工作表
    vExcelApp.OlePropertyGet( (WideString)L"Workbooks").OleFunction( (WideString)L"Add", 1); // 工作表
    // 操作这个工作表
    vSheet = vExcelApp.OlePropertyGet( (WideString)L"ActiveWorkbook")
            .OlePropertyGet( (WideString)L"Sheets", 1);
    // 设置Excel文档的字体
    vSheet.OleProcedure( (WideString)L"Select");
    vSheet.OlePropertyGet( (WideString)L"Cells").OleProcedure( (WideString)L"Select");
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"Size", dbg->Font->Size);
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"Name", dbg->Font->Name.c_str());
    vExcelApp.OlePropertyGet( (WideString)L"Selection").OlePropertyGet( (WideString)L"Font")
            .OlePropertySet( (WideString)L"FontStyle", (WideString)L"常规");
    vSheet.OlePropertyGet( (WideString)L"Cells", 1, 1).OleProcedure( (WideString)L"Select");
    // 表格的行数
    int nRowCount(dbg->DataSource->DataSet->RecordCount + 1);
    nRowCount = nRowCount < 2? 2: nRowCount;
    // 表格的列数
    int nColCount(dbg->Columns->Count);
    nColCount = nColCount < 1? 1: nColCount;
    //设置单元格的宽度
    for(int i=0; i<nColCount; i++)
    {
        int nColWidth = dbg->Columns->Items[i]->Width;
        vExcelApp.OlePropertyGet( (WideString)L"Columns", i + 1)
                .OlePropertySet( (WideString)L"ColumnWidth", nColWidth / 7);
    }

    // 先将列名写入Excel表格
    for(int j=0; j<dbg->Columns->Count; j++)
    {
        // 标题行的行高
        vExcelApp.OlePropertyGet( (WideString)L"Rows", 1).OlePropertySet( (WideString)L"RowHeight", 20);
        //
        vSheet.OlePropertyGet( (WideString)L"Cells", 1, j + 1)
                .OlePropertySet( (WideString)L"Value",
                dbg->Columns->Items[j]->FieldName.c_str());
        // 设置列名单元格的背景色
        Variant vInter = vSheet.OlePropertyGet(
                "Cells", 1, j + 1).OlePropertyGet( (WideString)L"Interior");
        vInter.OlePropertySet( (WideString)L"ColorIndex", 15); // 灰色
        vInter.OlePropertySet( (WideString)L"Pattern", 1); // xlSolid
        vInter.OlePropertySet( (WideString)L"PatternColorIndex", -4105); // xlAutomatic
	}
    // 将DBGrid中的数据写入Excel表格
    dbg->DataSource->DataSet->First();
    for(int i=0; i<nRowCount; i++)
    {
        // 普通数据行的行高16
        vExcelApp.OlePropertyGet( (WideString)L"Rows", i + 2).OlePropertySet( (WideString)L"RowHeight", 16);
        // 63 63 72 75 6E 2E 63 6F 6D
        for(int j=0; j<dbg->Columns->Count; j++)
        {
            vSheet.OlePropertyGet( (WideString)L"Cells", i + 2, j + 1)
                .OlePropertySet( (WideString)L"Value",
				(WideString)dbg->DataSource->DataSet->FieldByName(
                dbg->Columns->Items[j]->FieldName)->AsString);
        }
        dbg->DataSource->DataSet->Next();
	}

    // 保存Excel文档并退出
    vExcelApp.OlePropertyGet( (WideString)L"ActiveWorkbook")
			.OleFunction( (WideString)L"SaveAs", (WideString)strXlsFile);
    vExcelApp.OleFunction( (WideString)L"Quit");
    vSheet = Unassigned;
    vExcelApp = Unassigned;
    // 工作结束
    MessageBox(0, L"DBGrid2Excel 转换结束!",
            L"DBGrid2Excel", MB_OK);
现在这个问题已经解决了, 现在的问题是导出的excel被截断了 每个数只出了一半
123456jiihi 2015-03-31
  • 打赏
  • 举报
回复
好的 一会试试
宝龙哥 2015-03-31
  • 打赏
  • 举报
回复
这里指的每个字符串是指OLE相关的字符串,int和bool类型直接使用,String这种 strXlsFile.c_str());改为(WideString)strXlsFile
宝龙哥 2015-03-31
  • 打赏
  • 举报
回复
对于XE7系列,在每个字符串前面加上 (WideString)L ,比如 (WideString)L"Wrap" ,在文本控件前面加上 (WideString)Edit1->Text
123456jiihi 2015-03-31
  • 打赏
  • 举报
回复
引用 1 楼 kfrght 的回复:
对于XE7系列,在每个字符串前面加上 (WideString)L ,比如 (WideString)L"Wrap" ,在文本控件前面加上 (WideString)Edit1->Text
我试了下kfrght的方法,但是还是失败了,报的错是(不能设置类Range的ColumnWidth属性)这个错误,我改怎么办啊 ,求各位大神帮忙啊

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧