轉自:Linux系統使用PHP實現PPT轉圖片 - 盛世芳華 - 博客園 (cnblogs.com)
目前主流的實現方式爲先將PPT轉爲PDF,再將PDF轉成圖片。
1、安裝軟件
yum install nodejs npm unoconv libreoffice-dev imagemagick
centos安裝imagemagick提示找不到,先執行命令:
yum list ImageMagick*
然後安裝:
yum install ImageMagick.x86_64
2、安裝字體
創建字體目錄
mkdir -p /usr/share/fonts/win
然後將windows下的字體文件上傳到此目錄,執行命令使之生效
mkfontscale mkfontdir sudo fc-cache -fv
3、安裝nodejs擴展ppt2png
mkdir /opt/ppt cd /opt/ppt npm init npm install ppt2png
編寫腳本:
vim test.js
腳本代碼:
var ppt2png = require('ppt2png'); var ppt = process.argv[2]; var topath = process.argv[3]; ppt2png(ppt, topath, function( err ){ if(err) { console.log(err); } else { console.log('convert successful.'); } });
執行腳本:
node test.js 1.pptx ./test/hi
腳本執行後,先將1.pptx轉爲1.pdf,然後將1.pdf自動轉爲圖片,自動創建test目錄,生成hi-0.jpg,hi-1.jpg。
4、php調用腳本
創建test.php
<?php $output = shell_exec("whoami"); echo "<pre>I am $output</pre>"; ?>
瀏覽器訪問查看apache的用戶名,我的是apache,然後賦予root權限。
vim /etc/sudoers apache ALL=(ALL) NOPASSWD:ALL
然後在php頁面中調用腳本,調用時加上sudo:
<?php //堵塞方式 shell_exec('sudo node /opt/ppt/test.js /opt/ppt/3.ppt /opt/ppt/hello/hi'); //非堵塞方式 shell_exec("sudo node /opt/ppt/test.js /opt/ppt/3.ppt /opt/ppt/hello/hi > /dev/null 2>&1 &"); ?>
如果php頁面調用腳本時出現sudo: sorry, you must have a tty to run sudo
修改一下sudo的配置就好了
vim /etc/sudoers
註釋掉 Default requiretty 一行
#Default requiretty
意思就是sudo默認需要tty終端,註釋掉就可以在後臺執行了。
2021-12-25備註:
服務器centos7.5,nginx,php-fpm。
執行unoconv出現錯誤:
{ Error: Command failed: unoconv -f pdf -o /opt/pptconvert/test/hello.pdf /opt/pptconvert/1.pptx
Traceback (most recent call last):
File "/usr/bin/unoconv", line 1205, in <module>
run()
File "/usr/bin/unoconv", line 1199, in run
main()
File "/usr/bin/unoconv", line 1090, in main
convertor.convert(inputfn)
File "/usr/bin/unoconv", line 937, in convert
raise UnoException("Unable to store document to %s (ErrCode %d)\n\nProperties: %s" % (outputurl, e.ErrCode, outputprops), None)
File "/usr/lib64/python2.7/site-packages/uno.py", line 507, in _uno_struct__getattr__
return getattr(self.__dict__["value"], name)
AttributeError: ErrCode
說明有掛起的soffice
ps -ef | grep soffice.bin
kill掉所有的soffice線程即可。
php頁面中:
echo shell_exec('sudo node /opt/pptconvert/convert.js /opt/pptconvert/1.pptx /opt/pptconvert/test/hello');這種方式執行,頁面顯示空白。
echo shell_exec('node /opt/pptconvert/convert.js /opt/pptconvert/1.pptx /opt/pptconvert/test/hello');不加sudo執行,出現錯誤:
修改php-fpm.d/www.conf添加或者刪掉前面的#,
clean_env = no
然後重啓:
and the restart php-fpm systemctl restart php-fpm.service
但不加sudo的情況下,頁面訪問時一直轉圈,使用nginx身份執行命令:
sudo -H -u nginx bash -c "node /opt/pptconvert/convert.js /opt/pptconvert/1.pptx /opt/pptconvert/test/hello"
發現原來是卡在了touch /opt/pptconvert/test/convert這一行,改改 /opt/pptconvert/目錄解決這個問題。
所以兩種思路(僅限我的項目):
1、如果要在php中加sudo執行轉ppt操作,那就修改/etc/sudoers即可,如果是nginx,同時修改php-fpm.d/www.conf;
2、如果在php頁面中不加sudo執行轉ppt操作,那就要修改腳本安裝的路徑,不要放在opt目錄下,不然touch的時候沒有權限(默認不涉及touch命令,touch是我自己加的,爲了滿足我的項目)。
參考:php 怎麼執行unoconv,web執行php調用exec(unoconv)命令失敗解決方案
php web端不能調用shell_exec運行linux命令(unoconv爲例)
csv - unoconv return error when running as www-data - Stack Overflow
5、ppt2png插件代碼解析
/opt/ppt/node_modules/ppt2png/ppt2png.js爲核心功能。
代碼很簡單,調用unoconv將ppt轉爲pdf,調用convert命令將pdf轉爲圖片。
其默認轉出的圖片爲png,速度慢,可以修改代碼:
exec('convert -resize 1200 -density 200' + input + ' ' + output+'.png',
改爲:
exec('convert -resize 800 -density 72 ' + input + ' ' + output+'.jpg',
常見錯誤:
1、執行時如提示convert命令未找到,則重新安裝ImageMagick
yum install ImageMagick
# 測試是否安裝完成--查看是否有結果輸出
convert -v
2、Can't open display: Set DISPLAY environment variable, use -display option or check permissions of your X-Server
yum install libreoffice-headless
參考網址:
https://oomake.com/question/3133511
https://blog.csdn.net/liuxiao723846/article/details/97822207
http://blog.51yip.com/jsjquery/1924.html
https://www.liminghulian.com/article/202
https://blog.csdn.net/wuzuyu365/article/details/95988470
https://blog.csdn.net/pwtitle/article/details/51684685
https://blog.csdn.net/weixin_40816738/article/details/102847228
2024年1月19日補充
本次在ubuntu系統中部署。
1、安裝軟件
apt install nodejs npm unoconv libreoffice-dev imagemagick
2、安裝字體
apt install xfonts-utils
創建字體目錄
mkdir -p /usr/share/fonts/win
然後將windows下的字體文件上傳到此目錄,執行命令使之生效
mkfontscale mkfontdir sudo fc-cache -fv
3、創建新目錄
cd /opt/web/ mkdir ppt2img cd ppt2img/
npm init
4、之前是通過安裝ppt2png庫實現PPT轉圖片的,在ubuntu系統中執行總是出錯,所以我乾脆自己重寫了一下,創建app.js,代碼如下:
const { exec } = require('child_process'); var ppt2png = require('ppt2png'); var ppt = process.argv[2]; var topath = process.argv[3]; const command_pdf = 'unoconv -f pdf -o '+topath+'.pdf '+ppt; const command_png = 'convert -resize 1200 -density 200 ' + topath + '.pdf ' + topath + '.png'; exec(command_pdf, (error, stdout, stderr) => { if (error) { console.error(`轉換PDF執行錯誤:${error}`); return; }else{ console.error(`PDF轉換完成,開始生成圖片`); exec(command_png, (error, stdout, stderr) => { if (error) { console.error(`轉換PNG執行錯誤:${error}`); return; }else{ console.log('convert successful.'); } }); } });
5、測試
1
|
node app.js test.pptx ./test |
如果提示:convert successful,說明執行成功,會在當前目錄下生成test.pdf和test-*.png圖片序列。
如果執行時出現以下錯誤:
convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/408. convert-im6.q16: no images defined `cc.jpg' @ error/convert.c/ConvertImageCommand/3258.
那麼
1
|
vim nano /etc/ImageMagick-6/policy.xml |
將以下代碼註釋掉即可。
1
2
3
4
5
|
<policy domain= "coder" rights= "none" pattern= "PS2" /> <policy domain= "coder" rights= "none" pattern= "PS3" /> <policy domain= "coder" rights= "none" pattern= "EPS" /> <policy domain= "coder" rights= "none" pattern= "PDF" /> <policy domain= "coder" rights= "none" pattern= "XPS" /> |
參考網址:vim nano /etc/ImageMagick-6/policy.xml
6、通過php調用
在web目錄下創建ppt.php
1
2
3
4
5
6
|
<?php $output = shell_exec( "whoami" ); echo "<pre>I am $output</pre>" ; shell_exec( 'sudo node /opt/web/ppt2img/app.js /opt/web/ppt2img/asd.pptx /opt/web/ppt2img/hi >> /tmp/log.txt 2>&1' ); echo $output; ?> |
瀏覽器訪問ppt.php,查看當前用戶是誰,我的是www-data,使用shell_exec執行ppt轉圖片的程序沒成功,可以看下var/log/auth.log日誌,發現報錯:www-data:user not in sudoers,說明是因爲www-data沒用權限導致的。或者看一下/tmp/log.txt日誌的輸出。之所以輸出到/tmp中,是因爲當前用戶可能沒用權限輸出到opt目錄下。
7、修改www-data權限
1
2
3
4
5
|
chmod u+w /etc/sudoers vim /etc/sudoers root ALL=(ALL:ALL) ALL www-data ALL=(ALL) NOPASSWD:ALL chmod u-w /etc/sudoers |
再次web使用訪問ppt.php文件,PPT轉圖片成功。
注意:php中使用shell_exec調用轉換程序時,一定要寫sudo。