从 office 或者 pdf 中提取文字或者将其转换为图片

从 office 或者 pdf 中提取文字或者将其转换为图片

近期由于工作要求,需要将 word, ppt, excel 以及 pdf 中的文字提取出来用于检索,或者将其转换为图片,当然过程肯定是 Google 加 百度,为了避免重复劳动,今天花点时间整理一下,以免日后用到。整个过程其实依赖于开源软件:https://github.com/dagwieers/unoconv,整个
过程的实施是在 docker 环境中,下面就列出一些详细的过程,用的语言是 PHP,其他语言都差不多,大致过程如下:

构建 docker 镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
FROM 7.3.2-fpm-alpine3.9

# 替换阿里云镜像
RUN sed -i s,http://dl-cdn.alpinelinux.org,http://mirrors.aliyun.com,g /etc/apk/repositories \
&& apk add --update --no-cache

# 安装 GD 扩展
RUN apk update \
&& apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \
&& docker-php-ext-configure gd \
--with-gd \
--with-freetype-dir=/usr/include/ \
--with-png-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ \
&& NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) \
&& docker-php-ext-install -j${NPROC} gd \
&& apk del --no-cache freetype-dev libpng-dev libjpeg-turbo-dev

# 安装 imagick 扩展
RUN wget -O /tmp/imagick-3.4.3.tgz https://pecl.php.net/get/imagick-3.4.3.tgz \
&& pecl install /tmp/imagick-3.4.3.tgz \
&& docker-php-ext-enable xdebug \
&& rm -f /tmp/imagick-3.4.3.tgz

# 安装 unoconv
RUN apk add libreoffice python3 libxml2 libxslt \
&& apk add --virtual .unoconv-build build-base python3-dev py-setuptools libxml2-dev libxslt-dev libc-dev \
&& pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com unoconv pyquery \
&& apk del .unoconv-build

# 安装中文字体用于后续转换图片处理,否则汉字无法识别
RUN apk add wqy-zenhei --update-cache --repository http://nl.alpinelinux.org/alpine/edge/testing --allow-untrusted \
&& apk add --update font-adobe-100dpi ttf-dejavu fontconfig

# 安装tika
RUN apk add --no-cache openjdk8-jre \
&& wget https://mirrors.tuna.tsinghua.edu.cn/apache/tika/tika-app-1.20.jar -O /usr/lib/tika-app-1.20.jar


# install wkhtmltopdf
RUN apk add wkhtmltopdf

文档转图片

我们主要考虑以下五种类型文件,PPT, Word, Excel,HTML 以及 Pdf,他们最后都是转换成 PDF ,再从 PDF 转换成图片:

从 pdf 转换为 图片

可以使用 imagemaick convert 命令行工具转换或者 imagemaick 在各个语言中实现的扩展操作,例如:

convert -background white -alpha remove  -density 300 -quality 100  ss.pdf test.png
convert -background white -alpha remove  -density 300 -quality 100  ss.pdf test.jpeg 

这里的参数的意思可以查询官方文档,翻译成代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php

use Imagick;

function pdf2Image($source, $targetDir, $density = 480, $format = 'png')
{
if (!is_dir($targetDir)) {
mkdir($targetDir, 0777, true);
}

$results = [];

try {
for ($page = 1; ; $page++) {
$imagick = new Imagick();
$imagick->setResolution($density, $density);
$imagick->readImage(sprintf('%s[%s]', $source, $page - 1));
$imagick->setImageBackgroundColor('#FFFFFF');
$imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
if ($format == 'jpg' || $format == 'jpeg') {
$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$imagick->setImageCompressionQuality(70);
}
$imagick->setImageFormat($format);
$temp = tempnam($targetDir, "$page-");
$filename = $temp . ".$format";
$imagick->writeImage($filename);
unlink($temp);
$imagick->clear();
$results[] = $filename;
}
} catch (\ImagickException $exception) {
// 忽略该错误
}
return $results;
}

从 HTML 转换为图片

先将 HTML 转换为 pdf,再从 pdf 提取图片,可以使用工具:wkhtmltopdf

wkhtmltopdf test.html test.pdf

Docker for alpine 请看:https://hub.docker.com/r/madnight/docker-alpine-wkhtmltopdf/dockerfile

从 Excel 提取图片

  1. 先将 Excel 转换为 HTML,再从 HTML 转为 pdf,在提取图片,可使用工具:unoconv

    unoconv -f html -o test.html test.xlsx
    
  2. 将 Excel 转换为 PDF:

    libreoffice --headless --convert-to pdf:calc_pdf_Export --outdir ./ test.xlsx
    

从 word,PPT 提取图片

先将 PPT,Word 转换为 pdf,再从 pdf 转换为图片,使用工具:unoconv

unoconv -f pdf -o test.pdf test.docx
unoconv -f pdf -o test.pdf test.pptx

提取文字

提取文字使用工具,Apache-Tika,支持很多类型的文件,用法也很简单,由于是 Java 语言开发,所以 Java 中可以直接引入使用,其他语言,调用命令行程序即可:

java -jar tika-app-1.20.jar --text test.docx