因需要由資料庫資料,替換 word 文字,以提供下載,故選擇 OpenXML 元件進行開發。
1、需下載 DocumentFormat.OpenXml.dll , 自行 google OpenXml 就會出現下載點。
2、編譯時會出現需參考 WindowsBase.dll , 請自行參考。
程式碼如下:
private void button1_Click(object sender, EventArgs e)
{
string tPath = @"..\1.docx";
string tOutPath = string.Format(@"..\{0}.docx", DateTime.Now.ToString("yyyyMMddHHmmss"));
Dictionary <string, string> tReplaceDic = new Dictionary<string,string> ();
tReplaceDic.Add("§§name§§", "王小明");
tReplaceDic.Add("§§phone§§", "0912345678");
tReplaceDic.Add("§§address§§", "台北市忠孝東路1號");
tReplaceDic.Add("§§company§§", "google公司");
bool tResult = WordReplace(tPath, tOutPath, tReplaceDic);
if (tResult == true)
{
MessageBox.Show("OK");
}
else
{
MessageBox.Show("Not OK");
}
}
private bool WordReplace(string pTemplatePath, string pOutputFilePath, Dictionary<string, string> pReplaceDic)
{
bool tResultbool = true;
try
{
string tPath = pTemplatePath;
string tOutPath = pOutputFilePath;
if (File.Exists(tPath) == true)
{
//從範本COPY一份出來
File.Copy(tPath, tOutPath);
using (WordprocessingDocument tWordDocument = WordprocessingDocument.Open(tOutPath, true))
{
Body tBody = tWordDocument.MainDocumentPart.Document.Body;
foreach (KeyValuePair<string, string> tKeyVP in pReplaceDic)
{
string tSource = tKeyVP.Value;
string tTarget = tKeyVP.Key;
char[] tTargetArray = tTarget.ToCharArray();
foreach (Paragraph tParagraph in tBody.Descendants<Paragraph>())
{
//若尋找目標存在於此段落
if (tParagraph.InnerText.Trim().Contains(tTarget) == true)
{
int tIndex = 0; //Target Index
int tRunIndex = 0; // 目前 Run 的 Index
int tStartRun = 0; //啟始的 Run
string tStartString = string.Empty;
int tEndRun = 0; //最後的 Run
string tEndString = string.Empty;
bool tIsFindStart = false;
foreach (Run tRun in tParagraph.Descendants<Run>())
{
char[] tSourceArray = tRun.InnerText.Trim().ToCharArray();
bool tIsFind = FindWord(tTargetArray, tSourceArray, ref tIndex);
if (tIsFind == true)
{
if (tIsFindStart == false)
{
tIsFindStart = true; //記錄目前有找到Run
tStartRun = tRunIndex; //記錄第一個找到的Run
tStartString = tTarget.Substring(0, tIndex + 1);
tTargetArray = null;
tTargetArray = tTarget.Substring(tIndex + 1, tTarget.Length - (tIndex + 1)).ToCharArray();
tIndex = 0;
if (tTargetArray.Length == 0)
{
tEndRun = tRunIndex;
tEndString = tStartString;
break;
}
}
else
{
string tTempString = new string(tTargetArray);
tTargetArray = null;
tTargetArray = tTempString.Substring(tIndex + 1, tTempString.Length - (tIndex + 1)).ToCharArray();
tIndex = 0;
if (tTargetArray.Length == 0)
{
tEndRun = tRunIndex;
tEndString = tTempString;
break;
}
}
}
else
{
if (tIsFindStart == true)
{
tStartRun = -1;
tIsFindStart = false;
tTargetArray = null;
tTargetArray = tTarget.ToCharArray();
tIndex = 0;
tStartString = string.Empty;
tEndString = string.Empty;
}
}
tRunIndex++;
}
tRunIndex = 0;
foreach (Run tRun in tParagraph.Descendants<Run>())
{
if (tRunIndex >= tStartRun && tRunIndex <= tEndRun)
{
foreach (Text tText in tRun.Descendants<Text>())
{
if (tRunIndex == tStartRun || tStartRun == tEndRun)
{
tText.Text = tText.Text.Replace(tStartString, tSource);
}
else if (tRunIndex == tEndRun)
{
tText.Text = tText.Text.Replace(tEndString, "");
}
else
{
tText.Text = "";
}
}
}
tRunIndex++;
}
//重新設定一次要尋找的目標
tTargetArray = tTarget.ToCharArray();
}
}
}
tWordDocument.MainDocumentPart.Document.Save();
}
}
}
catch (Exception ex)
{
tResultbool = false;
}
return tResultbool;
}
private bool FindWord(char[] pTargetArray, char[] pSourceArray, ref int pTargetIndex)
{
bool tResultBool = true;
if (pSourceArray.Length > 0)
{
for (int i = 0; i < pSourceArray.Length; i++)
{
if (pSourceArray[i] == pTargetArray[pTargetIndex])
{
if ((pTargetIndex + 1) == pTargetArray.Length || (pTargetIndex + 1) == pSourceArray.Length)
{
break;
}
pTargetIndex++;
}
else
{
if ((pTargetIndex + 1) == pTargetArray.Length && (pSourceArray.Length - (pTargetIndex + 1)) == 0)
{
tResultBool = false;
pTargetIndex = 0;
break;
}
else
{
//重置 Source Array
string tTempString = new string(pSourceArray);
//一次右移一碼
char[] tSourceArray = tTempString.Substring(1, pSourceArray.Length - 1).ToCharArray();
//重置目標 index
pTargetIndex = 0;
tResultBool = FindWord(pTargetArray, tSourceArray, ref pTargetIndex);
break;
}
}
}
}
else
{
tResultBool = false;
pTargetIndex = 0;
}
return tResultBool;
}
小弟相信會有更好的寫法,此為筆記。