Форматировать значения обычного текста в столбцах, используя \t в php

У меня есть следующий код в php, когда я его выполняю:

<pre>
<?php
$input = '<xml>
<user>
    <name>sujit agarwal</name>
    <age>22</age>
    <gender>male</gender>
</user>
<user>
    <name>ajay rana</name>
    <age>25</age>
    <gender>male</gender>
</user>
<user>
    <name>pratap singh</name>
    <age>27</age>
    <gender>male</gender>
</user>
<user>
    <name>asdfasdfasdfasdf</name>
    <age>30</age>
    <gender>male</gender>
</user>
</xml>';
$sx = simplexml_load_string($input);
foreach($sx as $val)
echo $val->name."\t".$val->gender."\t".$val->age."\n";
?>
</pre>

ВЫВОД

sujit agarwal   male    22
ajay rana   male    25
pratap singh    male    27
asdfasdfasdfasdf    male    30

теперь моя проблема заключается в том, как выровнять все значения пола и возраста в столбце, даже если имя длиннее остальных. Надеюсь, я ясно изложил свою проблему. Это должно быть сделано в тегах PRE. потому что позже я сохраню это в файл TXT

НЕОБХОДИМО ФОРМАТИРОВАНИЕ

sujit agarwal       male    22
ajay rana           male    25
pratap singh        male    27
asdfasdfasdfasdf    male    30

person Sujit Agarwal    schedule 02.06.2011    source источник


Ответы (4)


<?php
$input = '<xml>
<user>
    <name>sujit agarwal</name>
    <age>22</age>
    <gender>male</gender>
</user>
<user>
    <name>ajay rana</name>
    <age>25</age>
    <gender>male</gender>
</user>
<user>
    <name>pratap singh</name>
    <age>27</age>
    <gender>male</gender>
</user>
<user>
    <name>asdfasdfasdfasdf</name>
    <age>30</age>
    <gender>male</gender>
</user>
</xml>';
$sx = simplexml_load_string($input);

$output='';
foreach($sx as $val){
    $values[] = $val->name;
    $values[] = $val->gender;
    $values[] = $val->age;
    $output.=vsprintf("%-30s %s\t %d",$values)."\n";
    $values='';
}

echo '<pre>';
echo $output;
echo '</pre>';
?>

выходы:

sujit agarwal                  male  22
ajay rana                      male  25
pratap singh                   male  27
asdfasdfasdfasdf               male  30
person Lawrence Cherone    schedule 02.06.2011
comment
Этот ответ явно не решает обобщенную проблему. Если name содержит более 40 алфавитов, ваша программа завершится ошибкой. - person Sujit Agarwal; 03.06.2011

Мне просто нужно было быстро сделать это для сценария оболочки, метод довольно переносим.

Просто передайте массив элементов с разделенной вкладкой столбцов, и он вернет отформатированную строку с правильно расположенными столбцами.

function function formatCols($rows)
{
  $colwidth = array();
  $rowsParts = array();
  $results = null;
  foreach ($rows as $row) {
    $cols = explode("\t", $row);
    $rowsParts[] = $cols;
    foreach ($cols as $id => $col)
      if (!isset($colwidth[$id]) || strlen($col) > $colwidth[$id])
        $colwidth[$id] = strlen($col);
  }
  $colFormat = null;
  for ($i=0; $i<count($colwidth); $i++)
    $colFormat .= '%-'.$colwidth[$i].'s ';
  $colFormat = trim($colFormat)."\n";
  foreach ($rowsParts as $row)
    $results .= vsprintf($colFormat, $row);
  return $results;
}
person Ben Lessani - Sonassi    schedule 17.05.2014

Это не слишком сложно.

Что вам нужно сделать, так это выяснить, насколько «широк» каждый столбец. А затем выясните, сколько вкладок вам нужно добавить к нему. Таким образом, вам нужно будет перебрать все строки дважды. Сначала определить для каждого столбца самое широкое значение, а затем «распечатать» данные плюс нужное количество вкладок.

Или вы можете просто использовать таблицы HTML, которые позаботятся об этом за вас, но я понимаю, что это не вариант.

person Halcyon    schedule 02.06.2011
comment
Я упомянул, почему мне нужно использовать \t в этом случае, потому что вывод должен храниться в обычных текстовых файлах. Мне не нужен html, потому что с помощью этого скрипта нечего отображать на веб-странице. - person Sujit Agarwal; 02.06.2011

Вам придется выполнить цикл дважды: 1, чтобы установить максимальную длину каждого отдельного поля, и второй, чтобы записать его с таким большим количеством пробелов (для чего я бы рекомендовал что-то вроде vsprintf('%45s %7s %-3d',$args); или любых других значений).

person Wrikken    schedule 02.06.2011
comment
Если вы имеете в виду не-HTML, то да, это просто ваши строки и пробелы, не более того, но очень простой однострочный тест мог бы вам это сказать. - person Wrikken; 02.06.2011