C# read/write/AddPicture PowerPoint
前言
最近工作有需求要用C#讀寫 PowerPoint,上網找了幾個方案:
1.Microsoft.Office.Interop.PowerPoint
免費(好像也不大對,Server端必須安裝Office軟體XD),傳統方式,不適用於Web多執行緒環境,否則多人同時存取時會發生一堆問題如下
https://support.microsoft.com/zh-tw/kb/257757
免費,但程式碼繁瑣,難以閱讀
3.Aspose.Slides for .NET、Spire.Presentation for .NET、GemBox.Presentation、Syncfusion
免費版有投影片張數限制,付費版價格我負擔不起XD
4.github上的PptxTemplater
免費,開放源碼,底層是Open XML SDK,推薦這個!已能解決大部份需求。
5.NetOffice,底層仍是Interop元件,雖有改善一些問題,但不推薦應用在實務上(尤其是Web環境)
以下分別介紹這幾天試了NetOffice和PptxTemplater這兩個元件使用心得。
NetOffice:http://netoffice.codeplex.com/
雖然它底層是Microsoft.Office.Interop,但至少解決一些問題※注意仍不適用於Web環境
實作
簡單說明NetOffice此元件該如何使用
1.先到官網下載壓縮檔 http://netoffice.codeplex.com/
2.解壓縮後到以下路徑找這幾個檔案,要複製加入自己的專案參考(自己專案是用.NET 4就到NET 4.0資料夾,若是用.NET 4.5的話就到NET 4.5資料夾)
3.加入參考後,確認該4個「內嵌Interop型別」屬性都設為False
4.預先準備一個PowerPoint檔,當做Template檔案。
如果要無中生有,從頭到尾使用程式碼寫出一份漂亮的PowerPoint,我覺得挺辛苦,很耗開發時間。
我的話,會先建立一份PowerPoint,之後程式碼就抓此檔案修改(或替換掉文字)即可。
上圖矩形內的數字,是我自己寫上去,為加入順序的矩形編號碼,待會程式碼會用到,增加可讀性。
5.使用C#打開PowerPoint,寫入文字和加入圖片
※此範例為Console專案
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
//操作檔案的引用
using System.IO;
//操作PowerPoint的引用
using NetOffice;
using PowerPoint = NetOffice.PowerPointApi;
using NetOffice.PowerPointApi.Enums;
using NetOffice.OfficeApi.Enums;
using NetOffice.PowerPointApi;
/*
* 語法語義都和操作Interop一樣,其他不懂操作的就用Interop關鍵字上網Google
*/
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//PowerPoint原始範例檔
string TemplatePath = @"D:\Template.pptx";
//複製成一份新的,準備編輯它
string newFilePath = Path.Combine(@"D:\",Guid.NewGuid().ToString()+".pptx");
File.Copy(TemplatePath,newFilePath);
// start powerpoint
using (PowerPoint.Application app = new PowerPoint.Application())
{
//打開檔案
Presentation presentation = app.Presentations.Open(newFilePath, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
for (int i = 1; i <= 5; i++)
{//加入5張投影片
//※PownerPoint的index都從1算起
int lastSlideIndex = presentation.Slides.Count;//目前投影片Total數量
presentation.Slides[lastSlideIndex].Copy();//複製最後一張投影片,準備編輯投影片
presentation.Slides.Paste();//貼上
//取得第i張投影片
Slide slide = presentation.Slides[i];
//※矩形順序為 當時該矩形加入投影片的順序,如果錯亂的話,就刪掉該矩形重新製作
//寫入第一個矩形文字
TextRange objTextRng1 = slide.Shapes[1].TextFrame.TextRange;
objTextRng1.Text = "我的標題:"+i;
//取得第二個矩形
Shape shape = slide.Shapes[2];
//圖片位置
string picturePath = @"D:\MyPicture_M.jpg";
slide.Shapes.AddPicture(picturePath,
MsoTriState.msoFalse, MsoTriState.msoTrue, shape.Left, shape.Top);
}//end for
//把最後一張投影片刪除
presentation.Slides[presentation.Slides.Count].Delete();
//存檔
presentation.SaveAs(newFilePath);
//釋放資源
app.Quit();
app.Dispose();
}//end using
}
}
}
6.結果
GitHub - tkrotoff/PptxTemplater:https://github.com/tkrotoff/PptxTemplater
底層是Open XML SDK,可適用於Web環境,現在很多讀寫Office文件的操作微軟都建議別用Interop元件,但Open XML SDK程式碼又很瑣碎,還好有大神整理出此開源碼(Orz膜拜一下~~
不過既然它取名為Templater,顧名思義,此元件沒辦法無中生有地建立一份PowerPoint,必須先手動製作一份PowerPoint,再用程式碼去修改它。
實作
1.先下載壓縮檔 https://github.com/tkrotoff/PptxTemplater
2.解壓縮後到以下路徑找這幾個類別檔案.cs,要複製加入自己的專案
※專案新增一個資料夾放這四個檔案(較好歸類)
3.由於底層是Open XML SDK,所以還必須加入相關參考
沒辦法找到組件參考的話,要先安裝 Open XML SDK (本文為2.5版本)
https://www.microsoft.com/en-us/download/details.aspx?id=30425
※System.Drawing組件也留意一下,應該也要加入
4.此元件的使用方式一定要預先準備一份PowerPoint檔,當做Template檔案。
之後程式碼就抓此檔案修改(或替換掉文字)即可。
大標題我先寫入{{myTitle}} 此關鍵字,稍後程式碼就抓這個取代文字
想要使用程式碼替換圖片的話,可以先選擇插入美工圖案>empty關鍵字搜尋>點選該透明圖片來插入圖片位置
該圖片還得命名一下,給稍後的程式碼抓
↑取名「照片1」
5.使用C#打開PowerPoint,新刪投影片並取代文字、圖片
※此範例為Console專案
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
//操作檔案的引用
using System.IO;
//操作PowerPoint的引用
using PptxTemplater;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//PowerPoint原始範例檔
string TemplatePath = @"D:\Template.pptx";
//複製成一份新的,準備編輯它
string newFilePath = Path.Combine(@"D:\", Guid.NewGuid().ToString() + ".pptx");
File.Copy(TemplatePath, newFilePath);
Pptx pptx = new Pptx(newFilePath, FileAccess.ReadWrite);
for (int i = 1; i <= 5; i++)
{//加入5張投影片
//取得每次最後一張slide
int nbSlides = pptx.SlidesCount();//取得slide數
PptxSlide lastSlide = pptx.GetSlide(nbSlides - 1);
PptxSlide newSlide = lastSlide.Clone();//複製slide
PptxSlide.InsertAfter(newSlide, lastSlide);//插入新slide
PptxSlide currentSlide = pptx.GetSlide(i - 1);//目前投影片,index從0算起
currentSlide.ReplaceTag("{{myTitle}}", "我的標題" + i, PptxTemplater.PptxSlide.ReplacementType.Global);
//圖片路徑
string picturePath = @"D:\myPicture.jpg";
currentSlide.ReplacePicture("照片1", picturePath, "image/jpeg");
}//end for
//把最後一張投影片刪除,index 從0算起
PptxSlide last = pptx.GetSlide(pptx.SlidesCount() - 1);
last.Remove();
//關檔
pptx.Close();
}
}
}
6.結果
結語
讀寫Office文件我只剩Word還沒寫過,其他它常見格式都已碰過
該用哪個元件提供個人經驗參考:
Excel:EPPlus > NPOI
PDF:iTextSharp(顯示繁體中文要額外處理,不知道此issue改善了沒)、或是找網頁轉PDF的免費元件
PowerPoint:PptxTemplater
Word:NPOI