Suite Utils
Back to Blog
NetSuite TipsSep 1, 2026 • 5 min read

Apparel Size Matrix Advanced PDF Template in NetSuite

Standard NetSuite POs print one line per item, hard to scan for apparel brands. Build an Advanced PDF template that groups lines into a size/color matrix.

Sarah Jenkins, CPASarah Jenkins, CPAPrincipal Finance Automation Specialist
Apparel Size Matrix Advanced PDF Template in NetSuite
On this page

Standard NetSuite purchase orders print one line per item, making them difficult to read quickly for apparel brands with multiple sizes and colors. Advanced PDF/HTML templates solve this by grouping transaction lines into a style/color matrix with sizes as columns. This article guides you through creating and implementing this template in NetSuite.

What the Matrix Template Does

The template snippet below reorganizes purchase order line items into blocks, showing one style and color combination per block with columns for each size ordered. Quantities for each size appear in their respective columns, and the template rolls up totals per group.

This approach also works on sales orders and invoices because it relies on the same record.item line structure those transactions share.

Configuration Before You Start

The template needs to know which custom fields hold your style, color, and size values. Set these at the top of the template:

<#assign STYLE_FIELD = "custitem_psgss_style_number" />
<#assign COLOR_FIELD = "custitem_psgss_product_color" />
<#assign SIZE_FIELD  = "custitem_psgss_product_size_desc" />
<#assign IMAGE_FIELD = "custitem_item_image" />
<#assign SHOW_ITEM_IMAGE_COLUMN = true />
<#assign MATRIX_DEBUG = false />
<#assign COLOR_OPTION_LABEL = "color" />
<#assign SIZE_OPTION_LABEL = "size" />

Use internal field IDs only. Do not prefix them with item. even if you see that format elsewhere in NetSuite documentation. The template's helper functions handle the lookup across line-level and item-level fields automatically.

Size Sorting Logic

Apparel sizes do not sort alphabetically. The template includes a rank map that assigns a numeric order to each size:

<#assign APPAREL_RANK = {
  "XXXS": 5,
  "XXS": 10,
  "XS": 20,
  "XS/S": 25,
  "S": 30,
  "S/M": 35,
  "M": 40,
  "M/L": 45,
  "L": 50,
  "L/XL": 55,
  "XL": 60,
  "XXL": 70,
  "2XL": 70,
  "XXXL": 80,
  "3XL": 80,
  "4XL": 90,
  "5XL": 100,
  "6XL": 110
} />

Add your own sizes to this map if your product line includes numeric sizes, kids' sizing, or extended sizes. The sort uses the rank value, so keep the numbers spaced to allow room for additions.

Handling Matrix Item Options

If you use NetSuite matrix items, the color and size values arrive as line options rather than custom fields. The template's getOptionValue function parses the options string on each line, which follows this format:

color: Navy, size: M

The function splits on the option label you configured in COLOR_OPTION_LABEL and SIZE_OPTION_LABEL, then extracts the value. This means the same template works whether you store attributes as custom fields or as matrix item options.

The Core Grouping Logic

The template builds a hash map where each key is a style + color combination. Every product line gets added to its group, and the size quantity accumulates into a nested map:

<#assign groupKey = styleVal + "||" + colorVal />

<#if !matrixGroups[groupKey]?has_content>
  <#assign matrixGroups = matrixGroups + {
    (groupKey): {
      "style": styleVal,
      "color": colorVal,
      "sizeMap": {},
      "sizeAmtMap": {},
      "sizeList": [],
      "totalQty": 0,
      "totalAmt": 0
    }
  } />
</#if>

Non-product lines like discounts, shipping, and tax get separated during this pass. Their totals appear in the summary section instead of cluttering the matrix.

Debugging Your Fields

Before you spend hours testing output, set MATRIX_DEBUG = true. This renders every line's raw field values directly in the document, showing you exactly what the template sees for style, color, size, quantity, and amount.

This step matters because NetSuite exposes different field shapes depending on how your account stores the data. A custom field on the item record behaves differently from a matrix option, and the template's fallback logic handles both. Debug mode tells you which path each line took.

Where to Paste the Template

Open the Advanced PDF/HTML template you want to modify:

  1. Navigate to Customization > Forms > Advanced PDF/HTML Templates
  2. Click Edit next to your purchase order template
  3. Switch to Code mode using the toggle at the top of the editor
  4. Locate the <#list record.item as line> loop in your existing template
  5. Insert the matrix block where you want the table to appear
  6. Click Save, then test with a real purchase order

The matrix block replaces the standard line-item table. Keep the rest of your template intact for headers, addresses, terms, and footer content.

Known Limitation: Item Images

The template supports showing product images in a dedicated column, but NetSuite's image serving can behave unpredictably. Images sometimes fail to render because the URL NetSuite generates requires authentication that the PDF renderer does not pass through.

If you hit this issue, set SHOW_ITEM_IMAGE_COLUMN = false and rely on the text-based matrix. The rest of the template works normally.

Why This Beats the Spreadsheet Workaround

Before this template, apparel teams often exported purchase order lines to Excel, rebuilt the matrix manually, and attached the spreadsheet to the PDF. That process introduced transcription errors and broke the audit trail, since the spreadsheet did not link back to the NetSuite transaction.

With the matrix template, the purchase order itself carries the grouped view. Your warehouse team reads sizes across the top and quantities in the body, and your auditors see one document with the full transaction detail. The template also handles the totals, so the bottom of the matrix matches the transaction total exactly.

If you need to adapt this for your own fields, the configuration block at the top is the only part you should have to touch. The grouping, sorting, and rendering logic works as a drop-in snippet.

Author Note

This article was written by Sarah Jenkins, CPA, Principal Finance Automation Specialist. She specializes in helping finance teams optimize NetSuite for month-end close automation, GAAP compliance, and multi-currency reporting.

About the author

Put these ideas to work.

Suite Utils builds small NetSuite tools that fix the specific thing breaking your day. Each one runs as a native SuiteScript SuiteApp inside your account. No sales call, no onboarding.

Browse the Tools

Enjoyed this one?

Get NetSuite tips like this in your inbox. No spam. Practical guides only.

Keep reading