Bash скрипт для редактирования файлов Excel
У меня есть несколько файлов Excel в этом формате.
Это часы и часы и дата и время.
--------------------------------- | Имя | Время | --------------------------------- | Человек А | 03.07.17 8:15 | | Человек А | 03.07.17 10:32 | | Человек А | 03.07.17 13:56 | | Человек А | 03.07.17 18:15 | | Человек А | 04.07.17 8:29 | | Человек А | 04-Jul-17 8:58 | | Человек А | 04.07.17 9:43 | | Человек А | 04-Jul-17 13:03 | | Человек А | 04.07.17 14:17 | | Человек А | 04-Jul-17 17:58 |,,, | Человек А | 31-Jul-17 7:45 | | Человек А | 31 июля 17: 8:10 | | Человек А | 31-июл-17 15:26 | | Человек А | 31-Jul-17 19:29 | ---------------------------------
Я хотел бы извлечь эти данные и сохранить их как новый файл Excel в этом формате:
--------------------------------------------- | Имя | Дата | Время в | Время истекло | --------------------------------------------- | Человек А | 03.07.17 | 8:15 | 6:15 вечера | | Человек А | 04-июл-17 | 8:29 | 17:58 |,,, | Человек А | 31 июля 17 | 7:45 | 7:29 вечера | ---------------------------------------------
По сути, это организовать данные одной записи в день с самым ранним временем для этой даты, как Time In
и самое позднее время для этой даты как Time Out
,
В этом формате есть несколько файлов Excel, и выполнение этого вручную займет слишком много времени.
Если вы хотите конвертировать их в .csv
сначала отредактируйте, а затем преобразовайте их обратно в .xlsx
, это круто.
PS: Щедрость 200 повторений за схватки.
3 ответа
Я преобразовал файлы в csv
и использовал PHP-скрипт для разбора контента, создавая его так, как я действительно хотел. Затем результат был сохранен в новом файле, затем эти файлы были преобразованы обратно в xls
затем слили в одну записную книжку.
Часть преобразования и слияния была сделана вручную. Это не лучшее решение, но оно работает на данный момент.
Вот сценарий:
// получить список файлов из каталога данных $files = array_diff(scandir('./data'), array('.', '..')); foreach($files как $ file): // получить все данные из файла csv и сохранить в массиве $ data $csvFile = file('data/'.$file); $data = $list = []; foreach($csvFile как $line) { $data[] = str_getcsv($line); } переменные не установлены ($ данные [0]); // анализируем массив данных и получаем разные разделы: name. Дата и время foreach($data as $v) { $date = strtotime($v[1]); $list[date('dm-Y',$date)][] = массив ('Имя'=>$v[0], 'Дата' => дата ('д / м /Y', дата $), 'В' => дата $); } // создаем новый массив и сохраняем в нем проанализированные данные со столбцами заголовков $new = array(array('Name','Date','Time In','Time Out')); foreach($list as $k => $v) { $out = max(array_column($v, 'in')); $name = $v[0]['name']; $new[] = array( 'Имя'=>ucwords(strtolower($ название)), 'Дата'=>$v[0]['дата'], 'in' => date ('h: i A', $ v [0] ['in']), 'out' => date ('h: i A', $ out)); } // Имя нового файла в новом каталоге с использованием этого имени файла $ filename = str_replace ('. csv', '', basename ($ file)); $ fn = strtolower ($ filename.'- log.csv '); // открыть файл и вывести новый массив как CSV $out = fopen('new/'.$fn, 'w'); foreach($new as $l) { fputcsv($out, $l, ",",'"'); } fclose($ из); endforeach;
Вам нужно 2 скрипта. Для преобразования из XLS в CSV используется команда xls2csv, а для другого - сценарий из github: csv2xls (другой csv2xls). Есть также csv2xlsx (и еще один csv2xlsx).
Между двумя преобразованиями вы можете редактировать файлы, используя ваш любимый инструмент.
Если вы хотите сделать это самостоятельно: xlsx-файлы (и то же самое относится к ODT (open/libeoffice) - это сжатые архивы и содержат XML-данные с данными. Вы можете разархивировать их, и данные будут в XML-формате. Сложнее, что CSV уверен, но когда манипулирование автоматизировано, оно становится довольно эффективным.
Благодаря @rinzwind мне удалось создать следующий скрипт bash, который распаковывает xlsx, использует sed для замены определенных строк на что-то другое, а затем снова архивирует его. Скрипт включает автовычисление, так что если у вас есть формулы, они тоже обновляются (по умолчанию нет).
#!/bin/bash
if ( [ -z $1 ] || [ -z $2 ] ); then
echo "Usage: create-xlsx.sh <PLACEHOLDER_A> <PLACEHOLDER_B>"
exit 1
fi
DIR=/tmp/mydir
rm -rf $DIR
mkdir -p $DIR
cd $DIR
#Note! xlsx is a zip-file
#Note! Original xlsx needs to have autocalculate set
#See https://stackoverflow.com/questions/18355691/set-xlsx-to-recalculate-formulae-on-open
unzip -d $DIR /path/to/original.xlsx
sed -i "s/calcPr iterateCount=\"100\"/calcPr calcMode=\"auto\" fullCalcOnLoad=\"1\" iterateCount=\"100\"/g" $DIR/xl/workbook.xml
sed -i "s/PLACEHOLDER_A/$1/g" $DIR/xl/worksheets/sheet1.xml
sed -i "s/PLACEHOLDER_B/$2/g" $DIR/xl/worksheets/sheet1.xml
zip -r /tmp/output.xlsx *