C#結(jié)合JS解決Word添加無(wú)效位圖導(dǎo)致進(jìn)程停滯的問(wèn)題
故障現(xiàn)象
最近在使用Word導(dǎo)出簡(jiǎn)歷的時(shí)候,發(fā)現(xiàn)在導(dǎo)出某些簡(jiǎn)歷數(shù)據(jù)的時(shí)候,服務(wù)器端 WORD 進(jìn)程停滯,頁(yè)面無(wú)響應(yīng)。最后發(fā)現(xiàn)問(wèn)題發(fā)生在使用 Word COM 方法 Word.InlineShape pic = WordApp.Selection.InlineShapes.AddPicture(filename,Type.Missing, true, Type.Missing); 時(shí)導(dǎo)致。在使用添加圖片方法時(shí),我們預(yù)生成了一個(gè)圖片,該圖片數(shù)據(jù)以二進(jìn)制數(shù)據(jù)保存在數(shù)據(jù)表中,Web 端可以通過(guò) Response.BinaryWrite 方法呈現(xiàn)到 Image 控件上,但生成圖片文件的時(shí)候,無(wú)法打開(kāi),提示無(wú)效的位圖文件,如下圖所示:

解決步驟
(1)將數(shù)據(jù)表中的二進(jìn)制數(shù)據(jù)讀出,將寫入到 Image 控件上進(jìn)行圖像呈現(xiàn)。
(2)在客戶端通過(guò) JS 創(chuàng)建畫布,將圖像數(shù)據(jù)繪制到畫布上,進(jìn)行重繪操作。
(3)通過(guò)畫布生成 Base64 編碼數(shù)據(jù),保存在臨時(shí)文本控件中。
(4)服務(wù)端將 Base64 方法重新生成正常位圖文件,再使用WordApp.Selection.InlineShapes.AddPicture方法實(shí)現(xiàn) Word 正常添加圖片。
開(kāi)發(fā)運(yùn)行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
Word 版:Microsoft Office Word 2016
.net版本: .netFramework4.7.2 或以上
開(kāi)發(fā)工具:VS2019 C#
關(guān)鍵代碼
呈現(xiàn)圖片到客戶端
假設(shè) Web 頁(yè)放置 ID 為 Image1 的Image控件,前端示例代碼如下:
<asp:Image ID="Image1" src="test.aspx" runat="server" width="110" height="160" />
test.aspx 后端輸出數(shù)據(jù)文件,示例代碼如下:
string _id="1001";
string _sql = "select imgdata from photos where id=@id ";
ArrayList para = new ArrayList();
para.Add(new SqlParameter("id", _id));
object rv=GetDataSet(_sql,paras);
DataSet ds = (DataSet)rv;
Byte[] _img= (Byte[])ds.Tables[0].Rows[0][0];
Response.ContentType = "image/*";//
Response.BinaryWrite(_img);
該代碼模擬從數(shù)據(jù)表提取二進(jìn)制字段(imgdata)數(shù)據(jù)通過(guò) Response.BinaryWrite 方法寫入并呈現(xiàn)數(shù)據(jù)。如何獲取數(shù)據(jù)集可參閱我的文章 《C# 利用IDbDataAdapter / IDataReader 實(shí)現(xiàn)通用數(shù)據(jù)集獲取》
重繪圖像
前端頁(yè)面布局兩個(gè)元素,一個(gè) ID 為 myCanvas 的畫布元素,一個(gè)用于存儲(chǔ) Base64 數(shù)據(jù)的 ID 為 ds 的文本框控件。
引用代碼如下:
<canvas id="myCanvas" style="display:none;"></canvas> <asp:TextBox runat="server" id="ds" TextMode="MultiLine" Text="" style="display:none"/>
以下代碼通過(guò) canvas 元素重繪圖像:
var img = document.getElementById("Image1");
img.onload = function () {
var canvas = document.getElementById("myCanvas")
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas1.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var image = canvas.toDataURL("image/png");
document.getElementById("ds").value = image;
}
引用 Image1對(duì)象,將畫布寬高設(shè)置為圖像的寬高,通過(guò) drawImage 方法進(jìn)行重繪操作,最后再通過(guò) canvas.toDataURL 方法將 Base64 數(shù)據(jù)寫入到 ds 臨時(shí)文本框控件中。
后端處理
通過(guò) Base64StringToImage 方法將 Base64 數(shù)據(jù)轉(zhuǎn)化為圖片文件,方法代碼如下:
public bool Base64StringToImage(string strbase64, string outputFilename)
{
byte[] arr = Convert.FromBase64String(strbase64);
MemoryStream ms = new MemoryStream(arr);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
img.Save(outputFilename);
img.Dispose();
if (File.Exists(outputFilename))
{
return true;
}
return false;
}
以下代碼實(shí)現(xiàn)最終生成可用的位圖文件:
string filename="d:\\test.png";
string base64Data = ds.Text.Trim().Replace("data:image/png;base64,", "");
Base64StringToImage(base64Data, filename);
關(guān)鍵部分需要替換掉臨時(shí)數(shù)據(jù)里的 “data:image/png;base64,” 文本,否則無(wú)法正常生成位圖文件。
小結(jié)
至此生成簡(jiǎn)歷數(shù)據(jù)正常,這是一種變通的做法,關(guān)于 WORD 的一些更多操作可參閱我的文章:
《C# 讀取二維數(shù)組集合輸出到Word預(yù)設(shè)表格》
《C# 操作 Word 全域查找且替換(含圖片對(duì)象)》
畫布繪制還可參閱我的文章:
《C# 結(jié)合JavaScript實(shí)現(xiàn)手寫板簽名并上傳到服務(wù)器》
到此這篇關(guān)于C#結(jié)合JS解決Word添加無(wú)效位圖導(dǎo)致進(jìn)程停滯的問(wèn)題的文章就介紹到這了,更多相關(guān)C#解決Word添加無(wú)效位圖導(dǎo)致進(jìn)程停滯內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#調(diào)用Matlab生成的dll方法的詳細(xì)說(shuō)明
這篇文章詳細(xì)介紹了C#調(diào)用Matlab生成的dll方法,有需要的朋友可以參考一下2013-09-09
C#如何給新建的winform程序添加資源文件夾Resources
這篇文章主要介紹了C#如何給新建的winform程序添加資源文件夾Resources,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
C#實(shí)現(xiàn)隨機(jī)數(shù)產(chǎn)生類實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)隨機(jī)數(shù)產(chǎn)生類,實(shí)例分析了C#隨機(jī)數(shù)的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
C# Soap調(diào)用WebService的實(shí)例
下面小編就為大家?guī)?lái)一篇C# Soap調(diào)WebService的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
C#靜態(tài)構(gòu)造函數(shù)用法實(shí)例分析
這篇文章主要介紹了C#靜態(tài)構(gòu)造函數(shù)用法,以實(shí)例形式較為詳細(xì)的分析了C#靜態(tài)構(gòu)造函數(shù)的用途、實(shí)現(xiàn)方法及使用技巧,需要的朋友可以參考下2015-06-06
淺析c#范型中的特殊關(guān)鍵字where & default
以下是對(duì)c#范型中的特殊關(guān)鍵字where和default進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09

