Fadly Dzil
Fadly Dzil

Reputation: 2206

PHP Create a string with predefined column and width

I have a standard data like this:

+------------+----------+-------+
| name       | position | width |
+------------+----------+-------+
| REFERENCE  |       20 |     9 |
| TRNSXN     |       48 |    14 |
| ESTIM_DATE |       64 |     8 |
+------------+----------+-------+
3 rows in set (0.00 sec)

My goal is to create a string where I can define the position and the width of each element, something like this

                   ETL                         E7954           20181123

As you can see first string is REFERENCE = "ETL"; starts on 20 and has a maximum 9 characters. if it has less, put space at the rest.

Then second string is TRNSXN = E7954; is start on 48 and have maximum 14 characters, if it has less, put space at the rest. So on, so on.

So far, this is my code:

private function preFormattedText($string, $width)
{
    return str_pad($string, $width, " ", STR_PAD_RIGHT);
}

public function actionHermesAnsi($id)
{
    $modelWestims =getDataAsAboveDescription ;


    $stringWestim = null;
    $stringWestim .= $this->preFormattedText('ETL', (int)$modelWestims[0]['width']);
    $stringWestim .= $this->preFormattedText('E7954', (int)$modelWestims[1]['width']);

    header("Content-type: text/plain");
    header("Content-Disposition: attachment; filename=westim.txt");

    print $stringWestim;
    exit();
}

I got ETL E7954 I can not define the position of it. Please help.

Upvotes: 2

Views: 138

Answers (3)

Fadly Dzil
Fadly Dzil

Reputation: 2206

Thanks for @Nesku and @Nick.

I use Nick's answer, a little modification based my needs like this:

private function formatStrings($strings, $positions)
{
    $position = 0;
    $returnString = null;
    foreach ($strings as $key => $str) {
        // do we need to move to a new position to display the next string?
        if ($positions[$key]['position'] > $position) {
            $returnString .= str_pad('', $positions[$key]['position'] - $position - 1);
            $position = $positions[$key]['position'];
        }
        // display the string
        $returnString .= str_pad($str, $positions[$key]['width']);
        $position += $positions[$key]['width'] - 1;
    }

    return $returnString;
}

Upvotes: 0

Nesku
Nesku

Reputation: 501

Maybe you can use STR_PAD_LEFT with the position like you did with the width, and remove the length of $stringWestim :

private function preFormattedText($stringWestim, $string, $width, $position)
{
    $string = str_pad($string, $position - strlen($stringWestim), " ", STR_PAD_LEFT );
    return str_pad($string, $width, " ", STR_PAD_RIGHT);
}

Upvotes: 1

Nick
Nick

Reputation: 147186

Something like this will do what you want:

function formatStrings($strings, $positions) {
    $position = 0;
    foreach ($strings as $key => $str) {
        // do we need to move to a new position to display the next string?
        if ($positions[$key]['position'] > $position) {
            echo str_pad('', $positions[$key]['position'] - $position - 1);
            $position = $positions[$key]['position'];
        }
        // display the string
        echo str_pad($str, $positions[$key]['width']);
        $position += $positions[$key]['width'] - 1;
    }
}

$strings = array('ETL','E7954','20181123');
$positions = array(array('position' => 20, 'width' => 9),
                   array('position' => 48, 'width' => 14),
                   array('position' => 64, 'width' => 8));
echo formatStrings($strings, $positions);

Demo on 3v4l.org

Upvotes: 2

Related Questions