DocForgeDocForge
TemplatesUse casesGlossaryHow-toPricingDevelopers
Sign inStart free
DocForgeDocForge© 2026
PricingAboutTemplatesUse casesGlossaryHow-toDevelopersTermsPrivacyRefundsContact

DocForge is a product of Rev Vision Ltd, registered in England & Wales (Company No. 14368830). Registered office: 86–90 Paul Street, London, England, United Kingdom, EC2A 4NE.

How-to guides

How-to guide

How to generate quotes from a CSV

Turn approved pricing rows into consistent customer quote PDFs with DocForge.

15 minute guide

What you'll need

Supplies

  • CSV with approved quote data
  • Quote terms and validity language
  • Customer and deal owner details

Tools

  • DocForge
  • Spreadsheet app
  • CRM export

Steps

  1. 1

    Export approved pricing rows

    Start from approved pricing, not a working sales spreadsheet. One row should equal one customer quote, with headers such as `quote_number,customer_name,contact_name,issue_date,valid_until,item_summary,subtotal,discount,tax,total,prepared_by`. Remove internal notes like margin, approval comments, and negotiation floor before upload. If a field should not appear in front of a prospect, it should not be in the CSV. Normalize dates to `2026-06-15` style values so the template can print `{{ row.valid_until | date: '%B %-d, %Y' }}` reliably. Keep discounts explicit: `discount` of `250.00` is clearer than burying the reduction in `subtotal`. Preview rows with large totals, short validity windows, and bundled item summaries. A quote for `Stark Industries Advanced Manufacturing Division` with `valid_until` only seven days after `issue_date` should make the deadline obvious. Quotes create commercial commitments, so treat the CSV as the approved source of truth.

  2. 2

    Choose the quote template

    Choose a template that makes the offer easy to approve. Put `customer_name`, `contact_name`, `quote_number`, `issue_date`, and `valid_until` near the top, then keep pricing in a compact table with `item_summary`, `subtotal`, `discount`, `tax`, and `total`. Avoid turning every sales note into fixed text. If renewal language, discount conditions, or implementation notes vary by quote, add deliberate CSV columns like `renewal_terms` or `discount_note` and wrap them conditionally: `{% if row.discount_note != blank %}{{ row.discount_note }}{% endif %}`. Use stock Liquid filters only, and rely on already formatted currency values where possible. For dates, `{{ row.valid_until | date: '%B %-d, %Y' }}` is enough when the CSV is clean. Check that `prepared_by` points to a real owner, such as `Maya Chen`, not an internal queue name. Prospects use that field when they reply with procurement questions.

  3. 3

    Preview realistic deal examples

    Preview quotes that stress the layout and the commercial logic. Include a small renewal, a large enterprise quote like `total` of `48250.00`, a bundled product summary, a long account name, and a quote with a short `valid_until` date. Compare the PDF to the approved pricing row, especially `quote_number`, `subtotal`, `discount`, `tax`, `total`, and `prepared_by`. If `discount` is blank, the document should not show an empty discount row; use a conditional such as `{% if row.discount != blank and row.discount != '0.00' %}...{% endif %}`. If `item_summary` contains semicolon-separated products, decide whether that reads well as one paragraph or should be exported as separate fields like `item_1_name` and `item_1_price`. Watch for quotes that spill onto a second page with only a signature line. That usually means the item descriptions are too verbose for batch generation and should be tightened in the source CSV.

  4. 4

    Generate and attach to deals

    Run the final quote batch only after the preview has been approved by the sales or finance owner responsible for pricing. Download the PDFs and attach each one to the matching deal, account, or customer record using `quote_number` as the primary key. File names like `Q-2026-1048_Stark-Industries.pdf` are easier to reconcile than generated row numbers. Keep the approved CSV with the output, because quote disputes usually come down to which `discount`, `valid_until`, or `prepared_by` value was live at generation time. If one row fails because `customer_name` is blank or `valid_until` is malformed, fix that row and regenerate a correction rather than editing the PDF manually. Before attaching, spot-check a high-value quote and a quote with optional terms. Conditional sections like `{% if row.renewal_terms != blank %}...{% endif %}` should either render complete language or disappear cleanly. A quote with half a sentence missing should never reach a prospect.

Related templates

Quote PDF template