Google Docs to Forms - Formswrite.com logo
BlogPricing

CSV to QTI Converter: Turn Spreadsheet Question Banks into Canvas, Moodle, and Brightspace Quizzes

FO

Formswrite Team

May 19, 2026

CSV to QTI Converter: Turn Spreadsheet Question Banks into Canvas, Moodle, and Brightspace Quizzes

CSV to QTI Converter: Spreadsheet Question Banks into LMS-Ready Quiz Packages

If you keep your question bank in a spreadsheet - a CSV pulled from a question-authoring tool, an exam committee's shared Google Sheet, or a textbook publisher's instructor materials - converting it into a quiz inside Canvas, Moodle, Brightspace, or Blackboard is a known pain. The LMS wants a QTI 2.1 .zip, your data is in rows and columns, and the schemas do not line up out of the box.
This guide shows the column conventions Formswrite's CSV-to-QTI converter expects, how to convert a single spreadsheet through the web app, and a small Python recipe for batch conversion through the API.
Open the CSV-to-QTI converter →

Why a CSV-to-QTI converter exists

QTI (Question and Test Interoperability) is the open standard every major LMS imports. A QTI package is a .zip of XML files plus an imsmanifest.xml index. The format is verbose: a single multiple-choice question in QTI 2.1 takes roughly 25 lines of XML. A 200-question bank is 5,000 lines.
Writing that by hand is impractical. Most people start from a spreadsheet because spreadsheets are how exam committees actually work. The job of a CSV-to-QTI converter is to translate a flat tabular layout into the QTI tree and bundle it into a valid package the LMS will accept.

CSV column conventions

The Formswrite converter accepts a flexible layout. The minimum viable CSV has four columns:
ColumnRequired?Notes
questionYesThe question stem. Markdown is allowed.
typeNoDefaults to multiple_choice. Other values: true_false, short_answer, essay, multiple_response, fill_blank, matching.
choice_a, choice_b, choice_c, …ConditionalRequired for multiple choice / multiple response. As many as you need.
correctYesThe correct choice letter(s). For multiple response, comma-separate (a,c).
pointsNoDefaults to 1.
feedback_correct, feedback_incorrectNoOptional per-question feedback strings.
image_urlNoA public URL to an image displayed above the question.
A sample row looks like this:
csvquestion,type,choice_a,choice_b,choice_c,choice_d,correct,points
"What is the capital of France?",multiple_choice,"Berlin","Madrid","Paris","Rome",c,1
"Photosynthesis produces oxygen.",true_false,,,,,true,1
"Name the largest planet in the solar system.",short_answer,,,,,Jupiter,2
The parser handles a few alternate header names automatically (stem for question, answer for correct, etc.) so a CSV exported from another LMS is usually accepted without renaming.

Convert through the web (single CSV)

  1. Open formswrite.com, sign in.
  2. Upload the CSV.
  3. Review the parsed questions. Anything ambiguous is flagged inline.
  4. Export as QTI 2.1 (.zip).
  5. Import the zip into your LMS (see per-LMS steps below).
This path is the fastest way to convert a single spreadsheet. For 50+ CSVs, switch to the API.

Convert through the API (batch)

Below is a working Python script that walks a folder of CSV files and converts each to a QTI package. Useful when migrating an entire course catalog.
pythonimport requests
from pathlib import Path

API_TOKEN = "your_formswrite_api_token"
INPUT_DIR = Path("./csv_question_banks")
OUTPUT_DIR = Path("./qti_packages")
OUTPUT_DIR.mkdir(exist_ok=True)

for csv_path in INPUT_DIR.glob("*.csv"):
    with csv_path.open("rb") as f:
        response = requests.post(
            "https://api.formswrite.com/v1/convert",
            headers={"Authorization": f"Bearer {API_TOKEN}"},
            files={"file": (csv_path.name, f, "text/csv")},
            data={"output_format": "qti_2_1"},
            timeout=120,
        )
    response.raise_for_status()
    out_path = OUTPUT_DIR / f"{csv_path.stem}.zip"
    out_path.write_bytes(response.content)
    print(f"converted {csv_path.name} -> {out_path.name}")
For very large workbooks, swap the synchronous call for the async endpoint (/v1/convert?async=true) and poll the job until ready.

Importing the QTI file

Canvas

Settings → Import Course Content → Content Type: QTI .zip file → Upload → Import. Questions land in Quizzes → Question Banks.

Moodle

Course → Question bank → Import → IMS QTI 2.1 format → Upload zip → Import.

Brightspace (D2L)

Course Admin → Import / Export / Copy Components → Import → select QTI zip. Full Brightspace-specific steps and gotchas in the Brightspace quiz import guide.

Blackboard Ultra

Course Content → Tests, Pools, and Surveys → Pools → Import Pool → upload zip.

Excel and Google Sheets

If your question bank lives in Excel (.xlsx) or a Google Sheet, the same converter accepts those formats directly - no need to export to CSV first. The same column conventions apply. For Google Sheets, connect your Google account once and pick the spreadsheet from the picker.

Common CSV pitfalls

  • Smart quotes ("curly quotes") from Word or Google Docs sometimes break naive CSV parsers. Formswrite handles them, but if you are using another converter, save the CSV as UTF-8 plain text first.
  • Empty trailing rows can confuse some importers. Trim before uploading.
  • Commas inside question text must be enclosed in double quotes. Most spreadsheet apps do this automatically on export.
  • Different LMSes round point values differently - if you specify 0.5 points per question, Canvas keeps the decimal; older Blackboard versions round to integers.

CSV-to-QTI vs. CSV-to-LMS-native

You can sometimes skip QTI entirely. Canvas accepts a Canvas-flavored CSV format directly (one column per question type). Moodle has its own GIFT format. If you are committed to a single LMS forever, the LMS-native format may be shorter to learn.
QTI is the right choice when:
  • You support more than one LMS (university with multiple departments, or a publisher distributing to schools).
  • You want your question bank portable between LMSes in the future.
  • You want to round-trip - pull questions out of one LMS, edit, push to another.

FAQ

Is the CSV-to-QTI converter free? Single conversions are free. Bulk and API use is paid.
What QTI version does the converter output? QTI 2.1 by default. QTI 2.2 is supported on request - useful for platforms that specifically require it.
Will it preserve images referenced by URL in my CSV? Yes - images at the URL in image_url are downloaded and embedded into the QTI package so they render even if the original URL goes down.
Can it handle math / equations in CSV cells? Yes - LaTeX between $…$ or \(…\) is converted to MathML so the LMS renders it as a real equation.
My CSV uses non-standard column names. Do I have to rename everything? No - the parser maps common alternates automatically (prompt, stem, answer_text, is_correct, etc.). Anything it cannot map is flagged in the preview.

Related guides

Ready to transform your documents?

Convert Google Docs, PDFs, and spreadsheets into forms with one click.

Start Now →

Or go straight to a converter: Google Docs to Forms, PDF to Google Form, Word to Google Form, Google Forms Quiz Generator


Share this post with your network

Back to Blog
Formswrite

Ask AI to compare Formswrite for you:

ChatGPTClaudeGeminiPerplexityGrok

Company

About usPricingContact usTerms of ServicePrivacy PolicyRefund PolicyAffiliate Program

Formswrite is the AI-powered form builder for educators, training centers, and businesses that need to convert documents into Google Forms, quizzes, and assessments without rebuilding from scratch. Upload a Google Doc, Word, PDF, image, or spreadsheet - Formswrite extracts the questions, structure, and grading rules, then exports to Google Forms, Canvas, Moodle, Kahoot, Quizizz, and more.

Trusted by educators, training teams, and HR departments worldwide. Formswrite's AI tools - quiz generator, worksheet generator, lesson-plan generator, rubric generator, and flashcard builder - are centralized in one platform.

Our brands

Docswrite logo

Docswrite

Zoral logo

Zoral

JobsPipe logo

JobsPipe

© 2026 Formswrite. All rights reserved.

Terms
Privacy
llms.txt
llms-full.txt