You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复VS2017中libxl开发Excel发票时的访问违例异常

Fix Access Violation Error When Saving Excel with libxl

Let's break down why you're hitting that access violation and fix it step by step:

The Root Cause: Accidental Assignment Instead of Comparison

Looking through your code, every if check for your Format pointers uses an assignment operator (=) instead of a comparison operator (==). For example:

if (titleFormat = nullptr) { // ❌ This assigns nullptr to titleFormat, then checks if the result is true
    titleFormat->setFont(titleFont);
}

Here's exactly what happens:

  1. You create a valid Format object with book->addFormat()
  2. The line titleFormat = nullptr overwrites that valid pointer with nullptr
  3. Since nullptr evaluates to false in a boolean check, the code inside the if block never runs
  4. Later, when you pass this nullptr to functions like sheet->writeStr(), libxl tries to access memory at the null address, leading to the access violation crash (which surfaces at save() because that's when the library processes all the format data).

Fixed Code

Here's your corrected main function with proper comparison checks and all format settings applied:

#include "libxl.h"
using namespace libxl;

int main() {
    Book* book = xlCreateBook(); // Use xlCreateXMLBook() for .xlsx files
    if (book) {
        Font* boldFont = book->addFont();
        if (boldFont) { // Add check for valid font pointer
            boldFont->setBold();
        }

        Font* titleFont = book->addFont();
        if (titleFont) {
            titleFont->setName(L"Arial Black");
            titleFont->setSize(16);
        }

        Format* titleFormat = book->addFormat();
        if (titleFormat != nullptr) { // ✅ Use != to check valid pointer
            titleFormat->setFont(titleFont);
        }

        Format* headerFormat = book->addFormat();
        if (headerFormat != nullptr) {
            headerFormat->setAlignH(ALIGNH_CENTER);
            headerFormat->setBorder(BORDERSTYLE_THIN);
            headerFormat->setFont(boldFont);
            headerFormat->setFillPattern(FILLPATTERN_SOLID);
            headerFormat->setPatternForegroundColor(COLOR_TAN);
        }

        Format* descriptionFormat = book->addFormat();
        if (descriptionFormat != nullptr) {
            descriptionFormat->setBorderLeft(BORDERSTYLE_THIN);
        }

        Format* amountFormat = book->addFormat();
        if (amountFormat != nullptr) {
            amountFormat->setNumFormat(NUMFORMAT_CURRENCY_NEGBRA);
            amountFormat->setBorderLeft(BORDERSTYLE_THIN);
            amountFormat->setBorderRight(BORDERSTYLE_THIN);
        }

        Format* totalLabelFormat = book->addFormat();
        if (totalLabelFormat != nullptr) {
            totalLabelFormat->setBorderTop(BORDERSTYLE_THIN);
            totalLabelFormat->setAlignH(ALIGNH_RIGHT);
            totalLabelFormat->setFont(boldFont);
        }

        Format* totalFormat = book->addFormat();
        if (totalFormat != nullptr) {
            totalFormat->setNumFormat(NUMFORMAT_CURRENCY_NEGBRA);
            totalFormat->setBorder(BORDERSTYLE_THIN);
            totalFormat->setFont(boldFont);
            totalFormat->setFillPattern(FILLPATTERN_SOLID);
            totalFormat->setPatternForegroundColor(COLOR_YELLOW);
        }

        Format* signatureFormat = book->addFormat();
        if (signatureFormat != nullptr) {
            signatureFormat->setAlignH(ALIGNH_CENTER);
            signatureFormat->setBorderTop(BORDERSTYLE_THIN);
        }

        Sheet* sheet = book->addSheet(L"Sheet1");
        if (sheet) {
            sheet->writeStr(2, 1, L"Invoice No. 3568", titleFormat);
            sheet->writeStr(4, 1, L"Name: John Smith");
            sheet->writeStr(5, 1, L"Address: San Ramon, CA 94583 USA");
            sheet->writeStr(7, 1, L"Description", headerFormat);
            sheet->writeStr(7, 2, L"Amount", headerFormat);
            sheet->writeStr(8, 1, L"Ball-Point Pens", descriptionFormat);
            sheet->writeNum(8, 2, 85, amountFormat);
            sheet->writeStr(9, 1, L"T-Shirts", descriptionFormat);
            sheet->writeNum(9, 2, 150, amountFormat);
            sheet->writeStr(10, 1, L"Tea cups", descriptionFormat);
            sheet->writeNum(10, 2, 45, amountFormat);
            sheet->writeStr(11, 1, L"Total:", totalLabelFormat);
            sheet->writeNum(11, 2, 280, totalFormat);
            sheet->writeStr(14, 2, L"Signature", signatureFormat);
            sheet->setCol(1, 1, 40);
            sheet->setCol(2, 2, 15);
        }

        // Save should now work without crash
        if (book->save(L"Invoice.xls")) {
            // Optional: Add success handling here
        } else {
            // Check if there was an error saving (e.g., permission issues)
            printf("Error saving file: %s\n", book->errorMessage());
        }

        book->release();
    }
    return 0;
}

Additional Notes

  • Never manually allocate Book with malloc: The xlCreateBook() function already handles creating and initializing the Book object for you. Using malloc creates an uninitialized block of memory that doesn't match libxl's internal Book structure, leading to undefined behavior.
  • Add checks for all libxl objects: I added checks for Font pointers as well, since addFont() can also return nullptr if there's a resource issue.
  • Error handling for save: Added a check on book->save() to catch any file-writing errors (like permission issues) and retrieve the error message for debugging.

内容的提问来源于stack exchange,提问作者A_Singh7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:46:38