[C++][Office] Excel 增益集自订另存新档及存成XPS、PDF问题
摘要:[C++][Office] Excel 增益集自订另存新档
在 Excel 增益集当中我们需要取得存档之后的文件名,所以在 WorkbookBeforeSave 事件当中进行尝试。
因为这个事件在存档前就已经触发了,无法取得使用者到底存成了什么文件名,所以我们取消掉 Office 自己调用的 SaveAs Dialog,让我们自行调用,这样就可以让使用者在我们自己产生的 Dialog 中存档,进行后续动作。
调用 SaveAsDialog 的方式有两种,各有优缺
如何自行调用 SaveAsDialog
1. 使用 Office::FileDialog,可以容易取得存档后的文件名、附档,但原本 PDF 及 XPS 档的发布选项将会不见
void CALLBACK CConnect::WorkbookBeforeSave(
Excel::_Workbook* Wb,
VARIANT_BOOL SaveAsUI,
VARIANT_BOOL* Cancel)
{
Office:: FileDialog* fileDialog;
*Cancel = true;
Wb->Application->get_FileDialog(Office::mosFileDialogSaveAs, &fileDialog);
if(fileDialog->Show() == VARIANT_TRUE)
{
fileDialog->Execute(); // 执行存档
}
else
{
//Do something if Cancel
}
}
2. 使用 XlBuiltInDialog,原有的 SaveAsDialog
void CALLBACK CConnect::WorkbookBeforeSave(
Excel::_Workbook* Wb,
VARIANT_BOOL SaveAsUI,
VARIANT_BOOL* Cancel)
{
*Cancel = true;
CComPtr App(Wb->Application);
CComPtr dlg = App->Dialogs->GetItem(Excel::XlBuiltInDialog::xlDialogSaveAs);
if(dlg->Show() == VARIANT_TRUE)
{
_bstr_t fileName = Wb->Name;
_bstr_t fullName = Wb->FullName[0];
}
else
{
//Do something if Cancel
}
}
Office::FileDialog 存成 PDF 或 XPS 时 需要另行处理
基本上以上两种都可以完成存档,但使用 Office::FileDialog 时发现如果另存为 PDF 或 XPS 两种格式文档时会有问题,文件是保存了没错,但是打开时两种都出现格式错误的问题,将他们的副文件名再改为.xlsx 时又可以用 EXCEL 开启,事实上根本就是假存档真改副文件名罢了。
要另存成 PDF 或 XPS 时需要调用 ExportAsFixedFormat,所以延伸第一种 Dialog 写法另做判断
void CALLBACK CConnect::WorkbookBeforeSave(
Excel::_Workbook* Wb,
VARIANT_BOOL SaveAsUI,
VARIANT_BOOL* Cancel)
{
Office:: FileDialog* fileDialog;
*Cancel = true;
Wb->Application->get_FileDialog(Office::mosFileDialogSaveAs, &fileDialog);
if(fileDialog->Show() == VARIANT_TRUE)
{
Office::FileDialogSelectedItemsPtr selectedItems = fileDialog->SelectedItems;
_bstr_t path = selectedItems.Item(1);
WCHAR ext[_MAX_FNAME]={0x00};
_wsplitpath(path, NULL, NULL, NULL, ext);
if(ext == L".pdf")
{
Wb->ExportAsFixedFormat(Excel::xlTypePDF, L"C:myExportPDF.pdf", vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing);
}
else if(ext == L".xps)
{
Wb->ExportAsFixedFormat(Excel::xlTypeXPS, L"C:myExportXPS.xps", vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing);
}
else
{
fileDialog->Execute(); // 执行一般格式存档
}
}
}
如何取得存档后的文件名
使用 Office::FileDialog,从 dialog 内取得参数
bool isCustomSaveAs = false;
void CALLBACK CConnect::WorkbookBeforeSave(
Excel::_Workbook* Wb,
VARIANT_BOOL SaveAsUI,
VARIANT_BOOL* Cancel)
{
if(isCustomSaveAs)
return;
// 没有显示 UI 表示他为"存档"事件
if(SaveAsUI != VARIANT_TRUE)
return;
isCustomSaveAs = true; //fileDialog.Show() 会再次触发此事件,需要滤掉
*Cancel = true; // 取消原本的另存新档行为
// 自订另存新档流程
CcomPtr App(Wb->Application);
Office::FileDialog* fileDialog;
App->get_FileDialog(Office::msoFileDialogSaveAs, &fileDialog);
if(fileDialog->Show() != VARIANT_TRUE)
return;
// 取得存档后的文件名
Office::FileDialogSelectedItemsPtr items = fileDialog->SelectedItems;
_bstr_t fileName = selectedItems->Items(1);
// 取得存档的类型
int typeIndex = fileDialog->FilterIndex;
Office::FileDialogFilterPtr flterPtr = fileDialog->GetFilters()->Item(typeIndex);
_bstr_t ext = flterPtr->GetExtensions();
}
使用 XlBuiltInDialog,从 Workbook 取得文件名
void CALLBACK CConnect::WorkbookBeforeSave(
Excel::_Workbook* Wb,
VARIANT_BOOL SaveAsUI,
VARIANT_BOOL* Cancel)
{
*Cancel = true;
CComPtr App(Wb->Application);
CComPtr dlg = App->Dialogs->GetItem(Excel::XlBuiltInDialog::xlDialogSaveAs);
if(dlg->Show() == VARIANT_TRUE)
{
// 存成 XPS、PDF 时取不到存档后的文件名,或许有方法,但我还没找到
_bstr_t fileName = Wb->Name;
_bstr_t fullName = Wb->FullName[0];
}
else
{
//Do something if Cancel
}
}
原文:大专栏 [C++][Office] Excel 增益集自订另存新档及存成XPS、PDF问题
原文地址:https://www.cnblogs.com/chinatrump/p/11458430.html
- Numpy 修炼之道 (2)—— N维数组 ndarray
- python爬虫入门(五)Selenium模拟用户操作
- python爬虫入门(六) Scrapy框架之原理介绍
- lambda表达式杂谈
- python爬虫入门(七)Scrapy框架之Spider类
- python爬虫入门(八)Scrapy框架之CrawlSpider类
- python爬虫入门(九)Scrapy框架之数据库保存
- Numpy 修炼之道(1) —— 什么是 Numpy
- TensorFlow修炼之道(3)——计算图和会话(Graph&Session)
- 1.python简介
- 《Python自然语言处理》答案第三章
- 2.python数据类型
- Miller Rabin算法详解
- 3.python文件操作
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP array_shift()用法实例分析
- PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
- 基于Python+QT的gui程序开发实现
- 使用tensorflow根据输入更改tensor shape
- 使用keras实现非线性回归(两种加激活函数的方式)
- Django Form设置文本框为readonly操作
- 浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
- keras和tensorflow使用fit_generator 批次训练操作
- php-fpm中max_children的配置
- python文件读取失败怎么处理
- PHP-FPM的配置与优化讲解
- python为什么会环境变量设置不成功
- keras自动编码器实现系列之卷积自动编码器操作
- PHP数字金额转换成中文大写显示
- 详解Python多线程下的list