最近在做兔兔答题时,要录入一批试题到数据库中。一共算下来,差不多有10w条之多。最简单的方法肯定是手动录入,但是10w条数据,工作量是真的太大了。
于是想到通过程序来录入吧,虽然需要花时间编写脚本程序。但做好之后,一直受益。
需求分析
1、需要将10w条数据录入到题库中。
2、这些文件都是word格式。
条件就这么简单。实现思路主要就是找word的解析库来实现。最开始找了一下Go语言的,发现Go语言在这方面的库很少,于是想着用Python吧,Python这么强,但Python又不是很熟悉,于是选择了PHP来实现。使用的是phpoffice的一个第三方库。
示例代码
大致的代码如下,也是非常的简答。
<?php
use PhpOffice\PhpWord\Element\Cell;
use PhpOffice\PhpWord\Element\Image;
use PhpOffice\PhpWord\Element\PreserveText;
use PhpOffice\PhpWord\Element\Row;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Element\Table;
use PhpOffice\PhpWord\Element\Text;
use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\IOFactory;
require_once './vendor/autoload.php';
ini_set('display_errors', true);
ini_set('max_execution_time', '0');
error_reporting(E_ALL ^ E_WARNING ^ E_NOTICE);
/**
* @author 兔兔答题
* @date 2023-12-11 11:40:59
* @link https://www.tutudati.com
* @license Apache
*/
class OfficeWord
{
public function importWord(string $filePath): array
{
return self::getWord($filePath);
}
public static function getWord($path = ''): array
{
$phpWord = IOFactory::load($path);
return self::getNodeContent($phpWord);
}
public static function getNodeContent($word): array
{
$return = [];
foreach ($word->getSections() as $section)
{
if ($section instanceof Section) {
foreach ($section->getElements() as $element)
{
if ($element instanceof TextRun) {
$text = '';
foreach ($element->getElements() as $ele) {
$text .= self::getTextNode($ele);
}
$return[] = $text;
} else if ($element instanceof Table) {
foreach ($element->getRows() as $ele)
{
$return[] = self::getTableNode($ele);
}
} else if ($element instanceof PreserveText) {
$text = implode('', $element->getText());
$return[] = $text;
}
}
}
}
return $return;
}
public static function getTextNode($node): string
{
$return = '';
if ($node instanceof Text)
{
$return .= $node->getText();
} else if ($node instanceof Image)
{
$return .= self::picToTxt($node);
} else if ($node instanceof TextRun) {
foreach ($node->getElements() as $ele) {
$return .= self::getTextNode($ele);
}
} else if ($node instanceof PreserveText) {
$return .= $node->getText();
}
return $return;
}
public static function getTableNode($node): string
{
$return = '';
if ($node instanceof Row) {
foreach ($node->getCells() as $ele)
{
$return .= self::getTableNode($ele);
}
} else if ($node instanceof Cell) {
foreach ($node->getElements() as $ele)
{
$return .= self::getTextNode($ele);
}
}
return $return;
}
public static function picToTxt($node): string
{
$imageData = $node->getImageStringData(true);
$imageData = 'data:' . $node->getImageType() . ';base64,' . $imageData;
return '<img src="'.$imageData.'">';
}
}
$workService = new OfficeWord();
var_dump($workService->importWord(__DIR__. "/兔兔知识竞赛活动双十二试题库练习.docx"));
最终的输出效果如下:
string(137) "12、同学丁某在网上卖游戏帐号,对方要求其缴纳保证金 2000元,丁某缴纳了保证金,这种做法是(1分)"
[76]=>
string(10) "A、正确"
[77]=>
string(10) "B、错误"
[78]=>
string(10) "答案:A"
[79]=>
string(210) "解析:网上购物一定要选择正规的渠道,并且要等收到货后进行确认,在付款。丁某的做法就违背了收货在付款,这种做法存在风险,故这种做法属于错误的。"
[80]=>
string(61) "淘宝双十一购物节是从哪一年开始的?(1分)"
[81]=>
string(11) "A、2010年"
[82]=>
string(11) "B、2012年"
[83]=>
string(11) "C、2009年"
[84]=>
string(11) "D、2011年"
[85]=>
string(10) "答案:C"
[86]=>
string(356) "解析:双十一是2009年开始的。 双十一购物狂欢节 ,源于淘宝商城 2009年11月11日举办的网络促销活动,当时参与的商家数量和促销力度有限,但营业额远超预想的效果。 于是11月11日成为天猫举办大规模促销活动的固定日期。发展到后期 都成为各大商家促销活动的节日。"
[87]=>
string(73) "淘宝在所有的双十一中,哪一年的销售额最高?(2分)"
[88]=>
string(11) "A、2020年"
[89]=>
string(11) "B、2021年"
[90]=>
string(11) "C、2018年"
[91]=>
string(11) "D、2019年"
[92]=>
string(10) "答案:D"
[93]=>
string(125) "解析:从数据上来看,2019年淘宝双十一的销售额达到了2684亿元,成为历年销售额最高的一年。"
非常的简单。
效率怎么样?