Search code examples
powershellcsvprintingxps

Print a txt-file containing tab characters using Powershell


I'm trying to write a script in Powershell to automatically print the contents of a text file. However, my tab characters are removed when printing making the final output hard to read.

I've provided an MWE to illustrate the issue.

Contents of MWE.txt (encoded in ANSI; a represents a tab character):

FOO→1,23→4,56

My powershell script:

$fname = "C:\MWE.txt"
Get-Content $fname | Out-Printer -name "Microsoft XPS Document Writer"

I'm using the XPS writer to avoid wasting paper, but in the end this will be changed to a real printer. The output on real paper is identical, I've ruled that out too.

Problem is that the in the print output, the tab characters are just erased, yielding:

FOO1,234,56

However, If I instead change the Out-Printer to Out-String, the console displays the file contents correctly. What on earth am I doing wrong? The file displays correctly with tabs in both notepad and notepad++, and I've tried UTF-8 encoding as well.

Edit 2018-07-12 10:20

Content structure of the file I'm trying to print, which is automatically generated by a system and put on a web server for which I have no access. For clarity, I've used to denote the tab character and · to denote a space:

MWE·-·TestFile·:·

0)→Time
1)→Temperature·1
2)→Humidity
3)→Pressure·A-B
4)→Pressure·A-C
5)→Pressure·D-C

0)···················→1)→2)→3)→4)→5)→
2018-07-04 12:00:00→22,03→5,34→18,93→23,10→10,10
2018-07-04 13:00:00→21,99→5,22→18,75→23,56→10,00
2018-07-04 14:00:00→21,99→5,17→18,55→23,54→10,15
2018-07-04 15:00:00→22,03→5,25→18,73→23,41→8,33

Solution

  • I have no explanation - the symptom sounds like a bug (that also affects the Microsoft Print To PDF printer) and it seems to be specific to tab characters, whereas spaces work fine.

    However, I can offer a workaround - assuming that the end goal is to create aligned output columns and that it isn't necessary to use tabs specifically to achieve that:

    Get-Content "C:\MWE.txt" | ForEach-Object {
      # Construct a custom object whose properties contain the
      # tab-separated tokens on the input line.
      $obj = New-Object PSCustomObject; $i = 0
      foreach ($val in $_ -split "`t") {
        Add-Member -InputObject $obj -NotePropertyName ('col' + ++$i) -NotePropertyValue $val 
      }
      $obj
    } | Format-Table -Property (1..6 | % { 'col' + $_ }) -HideTableHeaders | 
          Out-Printer -Name "Microsoft XPS Document Writer"
    
    • The ForEach-Object script block splits each input line into tokens by tabs and constructs a custom object with properties containing the individual tokens.

    • Format-Table creates table output with columns that use spaces for alignment; -HideTableHeaders suppresses output of a table header, which would normally display the (autogenerated) property names.

      • Note that since the input has lines with varying column counts, -FormatTable has to be instructed explicitly as to which columns to display, which is what (1..6 | % { 'col' + $_ }) does: it creates an array of all the auto-generated column names based on the assumption that at most 6 columns can be present, which is true of your sample input - adjust that number as needed. (To be safe, you may also specify a higher number, say, 20, but that will slow processing down.
    • Piping Format-Table's output to Out-Printer -Name "Microsoft XPS Document Writer" seems to result in the desired tabular output with aligned columns.

      • If column values end up getting truncated (indicated by ...), you need to tweak the Format-Table call, such as with custom column widths - see this answer of mine.

    Running this against your sample input yields the following 6-column layout in the console, and the output XPS document renders similarly:

    MWE·-·TestFile·:·                                                                                                                                                                   
    
    0)                    Time                                                                                                                                                          
    1)                    Temperature·1                                                                                                                                                 
    2)                    Humidity                                                                                                                                                      
    3)                    Pressure·A-B                                                                                                                                                  
    4)                    Pressure·A-C                                                                                                                                                  
    5)                    Pressure·D-C                                                                                                                                                  
    
    0)··················· 1)            2)   3)    4)    5)                                                                                                                             
    2018-07-04 12:00:00   22,03         5,34 18,93 23,10 10,10                                                                                                                          
    2018-07-04 13:00:00   21,99         5,22 18,75 23,56 10,00                                                                                                                          
    2018-07-04 14:00:00   21,99         5,17 18,55 23,54 10,15                                                                                                                          
    2018-07-04 15:00:00   22,03         5,25 18,73 23,41 8,33