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 *
Другие вопросы по тегам