在 alpine 中使用 NPOI Intro 在 .net 中常使用 NPOI 來做 Excel 的導入導出,NPOI 從 2.4.0 版本開始支持 .netstandard2.0,對於.net core 應用也可以使用 DotNetCore.NPOI。 對於 .NET Core 應用來說,如果沒 ...
在 alpine 中使用 NPOI
Intro
在 .net 中常使用 NPOI 來做 Excel 的導入導出,NPOI 從 2.4.0 版本開始支持 .netstandard2.0,對於.net core 應用也可以使用 DotNetCore.NPOI。
對於 .NET Core 應用來說,如果沒有特殊的需求,alpine 是最適合容器化的基礎 docker 鏡像,因為鏡像大小比較小,無論是對於打包還是下載都很快。
在我的一個 asp.net core 應用中有一個使用 NPOI 導出 Excel 的功能,我的應用的通過 docker 部署在 k8s 上的,而 docker 鏡像是基於 alpine 的,使用到了 NPOI 導出一個 excel
NPOI 的跨平臺實現依賴於 System.Drawing.Common
,System.Drawing.Common
在 Linux 上的實現依賴 libgdiplus,需要安裝 libgdiplus
才能正常工作,如果沒有 libgdiplus
會遇到類似下麵這樣的異常:
在 Linux 上使用 System.Drawing.Common
- 在 Ubuntu 上安裝
libgdiplus
,參考 https://www.hanselman.com/blog/HowDoYouUseSystemDrawingInNETCore.aspx
:
sudo apt-get install libgdiplus libc6-dev
- 在 alpine 上安裝
libgdiplus
.netcore 打包 docker 鏡像的時候我一般選擇 alpine 為基本的鏡像,因為鏡像本身比較小,下載打包都會很快很方便,於是就要找一下是不是可以在 alpine 上安裝 libgdiplus,如果不行的話就只好換鏡像了
在 alpine 的 packages 網站上找到了 libgdiplus, https://pkgs.alpinelinux.org/packages?name=libgdiplus&branch=edge
目前仍處於測試階段,還未正式發佈,不過已經可以使用,可以通過下麵的命令來在 alpine 上安裝
apk add libgdiplus --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
More
安裝了 libgdiplus
之後,重新部署再導出測試一下,發現還是不行,現在爆的異常如下:
根據異常提示找到異常的源碼 https://github.com/tonyqus/npoi/blob/master/main/SS/Util/SheetUtil.cs#L445
看異常提示以及代碼應該是沒有字體導致的異常,然後就在安裝 libgdiplus
之後再安裝一下字體,隨便找了一個字體安裝了,安裝的是 terminus-font
,裝了字體之後再測試,就可以正常導出了~
使用的 Dockerfile ,完整 Dockerfile 見:https://github.com/WeihanLi/ActivityReservation/blob/dev/Dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime-alpine
RUN apk add libgdiplus --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted && \
apk add terminus-font
# ...
Reference
- https://www.hanselman.com/blog/HowDoYouUseSystemDrawingInNETCore.aspx
- https://github.com/tonyqus/npoi/wiki/How-to-use-NPOI-on-Linux
- https://pkgs.alpinelinux.org/packages?name=libgdiplus&branch=edge
- https://github.com/tonyqus/npoi/blob/master/main/SS/Util/SheetUtil.cs