在 alpine 中使用 NPOI
Intro
在 .net 中常使用 NPOI 来做 Excel 的导入导出,NPOI 从 2.4.0 版本开始支持 .netstandard2.0,在 dotnet 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