这次玩一点不一样的.

最近因为做ppt,总发现有2件事情让我很烦恼:
我有一些PPT模版,但是需要找到一个合适的风格来表达当前的需求比较难,在目前的情况下,我只能一个一个先从文件名过滤,然后再一个一个的打开精确过滤;
确定了ppt的总体风格后,面对某些特殊的页面,模版中的一些单页PPT没法很好的符合我当前页的需求,我只能再一个一个的去打开PPT模版,去找相对合适的PPT;
所以,我就想是不是有一个插件,能让我导入我自己的ppt模版,然后能给我一个搜索框,能精确的搜索我想要ppt页的这种功能.看上去需求挺简单,但是开始找到的插件没有一个是能满足这个需求.不过还真有几款比较有意思的插件,使用起来怎么说呢,只能说感觉一般.质量也是参差不齐,各有侧重.但是对于资源基本都是内置选用型,没有自己导入型再给与搜索的.
那就自己写一个试试看!
在自己动手的过程中,我发现了VSTO这个不错的小玩意.Microsoft出品,.Net可控.作为一个很久很久没有动手写c#的我,现在的状态真的又一次坐实了"基本不会.Net了".-By the way:这可能是我这辈子的标签了.
我在网上找了好久VSTO的资料,发现网上关于PPT插件的操作大部分都是基于一个叫Spxxx什么的软件,这个软件试用版有限制,收费版好贵啊....算了,对于一个追求自力更生的我来说,原生的操作才是最爱.
到目前,我完成的功能不多,并且都是demo性质的.我现在的想法就是先把demo完成,所有的技术点试验完成后,整合起来即可.
这期先给记录一下,PPT整理阶段的一些远程VSTO操作:
PS:
所有的代码都是需要引用VSTO相关的dll进行的,对于另外特殊的dll引用,会另行告知
所有的代码都是demo,未考虑出错,资源释放等问题
ppt中的每一页导出成图片.纯VSTO操作就是香!
/*
* 将会根据ppt文件的全名,在ppt所在的文件夹下新建一个img文件夹,将导出的图片全部保存到这个img文件夹.
* 注意:不支持一个文件夹多个ppt,因为操作一个ppt会检查一次img文件夹,存在即删除
* pptPath -> ppt文件的全名
*/
using Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Core;
public static void Export2Img(string pptPath)
{
var app = new Application();
var ppt = app.Presentations.Open(pptPath,
MsoTriState.msoFalse,
MsoTriState.msoFalse,
MsoTriState.msoFalse);
var index = 0;
Console.WriteLine("ppt -> %s ", pptPath);
var fullpath = Path.GetDirectoryName(pptPath);
var imgpath = fullpath + @"\img\";
if(Directory.Exists(imgpath))
{
Directory.Delete(imgpath,true);
}
Directory.CreateDirectory(imgpath);
foreach (Slide slid in ppt.Slides)
{
++index;
//设置图片大小
// 不需要设置大小即为默认比率的大小,不设置不会失真
slid.Export(imgpath + string.Format("{0}.png",
index.ToString()),
"png");
}
//释放资源
ppt.Close();
app.Quit();
GC.Collect();
}
public static void CleanupText(string pptPath)
{
var app = new Application();
var ppt = app.Presentations.Open(pptPath,
MsoTriState.msoFalse,
MsoTriState.msoTrue,
MsoTriState.msoFalse);
StringBuilder st = new StringBuilder();
foreach (Slide slide in ppt.Slides)
{
int count = slide.Shapes.Count;
for (int i = 1; i <= count; i++)
{
if (slide.Shapes[i].HasTextFrame ==
MsoTriState.msoTrue)
{
st.Append(slide.Shapes[i].TextFrame.TextRange.Text);
string orgtxt = slide.Shapes[i].TextFrame.TextRange.Text;
string txt = orgtxt.Trim().Replace(" ", "");
if (0 <= txt.IndexOf("需要被替换的字"))
{
txt = txt.Replace("需要被替换的字", "替换的字");
}
slide.Shapes[i].TextFrame.TextRange.Text = txt;
}
}
Console.WriteLine(st);
}
// 这句一定要有,否则所有的更改都不会被保存
ppt.AcceptAll();
//释放资源
ppt.Close();
app.Quit();
GC.Collect();
}
public static void Do(string pptPath)
{
var app = new Application();
var ppt = app.Presentations.Open(pptPath,
MsoTriState.msoFalse,
MsoTriState.msoFalse,
MsoTriState.msoFalse);
var index = 0;
Console.WriteLine("ppt -> %s ", pptPath);
var fullpath = Path.GetDirectoryName(pptPath);
var imgpath = fullpath + @"\paging\";
if (Directory.Exists(imgpath))
{
Directory.Delete(imgpath, true);
}
Directory.CreateDirectory(imgpath);
foreach (Slide slid in ppt.Slides)
{
++index;
var newapp = new Application();
var newppt = newapp.Presentations.Add(MsoTriState.msoFalse);
PpSaveAsFileType format = PpSaveAsFileType.ppSaveAsDefault;
newppt.Slides.InsertFromFile(pptPath, 0,index ,index);
newppt.SaveAs(imgpath + string.Format("{0}.pptx",
index.ToString()), format,
MsoTriState.msoFalse);
newppt.Close();
newapp.Quit();
}
//释放资源
ppt.Close();
app.Quit();
GC.Collect();
}
public static void ModifyAttribut(string filename)
{
DSOFile.OleDocumentProperties dso = new DSOFile.OleDocumentProperties();
dso.Open(filename, false, DSOFile.dsoFileOpenOptions.dsoOptionOpenReadOnlyIfNoWriteAccess);
dso.SummaryProperties.Title = "标题";
dso.SummaryProperties.Subject = "Subject";
dso.SummaryProperties.Company = "Company";
dso.SummaryProperties.Author = "作者";
dso.SummaryProperties.Comments = "备注";
dso.SummaryProperties.Keywords = "关键字";
dso.Save();
dso.Close(false);
}
但是到目前为止,对于ppt的页面检测,我还是有一个没有想明白的.我们都知道ppt的页面有很多的图形组成,这些图形的组成中,我们都是会填写信息的.这些信息有的是一项,有的是两项,或者三项,四项...n项.我想通过程序如何能区分出来这个ppt页面到底是几项表示,这是其一.其二,我如何能分析出这个图形到底是一个什么图形,比如是鱼骨图,齿轮图等等...
写了这些的VSTO的代码,个人感觉VS作为IDE还是全宇宙第一的.另外VSTO确实蛮好玩的,和PPT这种office联合起来确实能做很多的事情,就像我的预想一样,虽然问题很多,但是至少解决方案还是不错.
PS:在运行的过程中,编译的时候一定要选择CPU为x86,而不是AnyCpu,否则运行出错.
最后一个,也是最折腾的一个,"干坏事"专用.更改文件的属性页中指定的属性.这个功能需要DSOFile支持,也是Microsoft出品.官网下载即可.
分割每个PPT页为一个单独的PPT,保存在ppt同目录的split目录下.
替换ppt中所有的文本框中指定的字




