从 c# 端点获取处理后的 word 文件到 nodejs 服务器

Get processed word file from c# endpoint to nodejs server

我有一个 nodejs 服务器用 axios to a c# endpoint with json as a parameter. My c# api uses Newtonsoft.Json to deserialize the json, then it reads a word file into memory, and inserts data. The final step I need is for this api to respond by sending the modified document back to the nodejs server. Currently, the c# endpoint is called, and a response is sent back. Upon writing the word document using the archiver library 发送 GET 请求并打开它,出现一个对话框,说“Word 在 export0.docx 中发现不可读的内容。你想恢复内容吗此文档的来源?如果您信任此文档的来源,请单击“是”

async exportToDotnet() {
    return await axios.get(`https://localhost:8082/test/${JSON.stringify(this)}`, { responseType: 'arrayBuffer' }).catch(err => {
        console.log(`ERR `, err);
    }).then((axiosResponse) => {
        const data = axiosResponse.data;
        console.log(`DATA `, data);
        console.log(`DATA LENGTH '${data.length}'`);
        return data;
    });
}

async function writeZipFile(resultFromExportToDotnet) {
    const output = createWriteStream('exported.zip');
    output.on("close", () => {
        console.log("success????");
    });
    const archive = archiver('zip');
    archive.on('error', (err) => {
        console.log('error in archive ', err);
    });
    archive.append(form, { name: `export0.docx` });
    archive.pipe(output);
    await archive.finalize();
}
[HttpGet("test/{json}")]
    public byte[] ExportDocumentBuffer(string json)
    {
        Console.WriteLine("Called");
        //Converts the json passed in to a FormInstance Object
        FormInstance form = JsonConvert.DeserializeObject<FormInstance>(json);
        //Read the dotx into memory so we can use it. Would it be better to just use System.IO.File.ReadAllBytes()?
        MemoryStream dotxBytes = ReadAllBytesToMemoryStream("test.dotx");
        //Read the file bytes into a WordProcessingDocument that we can edit
        WordprocessingDocument template = WordprocessingDocument.Open(dotxBytes, true);
        template.ChangeDocumentType(WordprocessingDocumentType.Document);
        template = ParseFormAndInsertValues(form, template);
        byte[] output = dotxBytes.ToArray();
        Console.WriteLine($"BYTES '{output.Length}'");
        return output;
    }
    ///<summary>Reads all Bytes of the provided file into memory</summary>
    ///<param name="path">The path to the file</param>
    ///<returns>A MemoryStream of the file data</returns>
    public static MemoryStream ReadAllBytesToMemoryStream(string path)
    {
        byte[] buffer = System.IO.File.ReadAllBytes(path);
        MemoryStream destStream = new MemoryStream(buffer.Length);
        destStream.Write(buffer, 0, buffer.Length);
        destStream.Seek(0, SeekOrigin.Begin);
        return destStream;
    }

我尝试过的事情

function stream2buffer(stream) {

    return new Promise((resolve, reject) => {

        const _buf = [];

        stream.on("data", (chunk) => _buf.push(chunk));
        stream.on("end", () => resolve(Buffer.concat(_buf)));
        stream.on("error", (err) => reject(err));

    });
}
    HttpResponseMessage result = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(dotxBytes.ToArray())
            };
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
            {
                FileName = "exampleName.docx"
            };
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 

记录 byte[] 的长度和记录 data.length 产生 2 个不同的数字(分别为 52107 和 69476)。这只是一个序列化问题吗?显然我错过了一些东西。任何帮助将不胜感激!

结果是一些事情:我使用了 template = WordProcessingDocument.Open(),但从未调用过 template.Save()template.Close(),因此,我的更改从未被写入,文件是还开着。获得字节数组输出后,我使用 Convert.ToBase64String(output) 并返回字符串。在 NodeJs 端,我将响应类型更改为 'text',并返回 Buffer.from(axiosResponse.data, 'base64'); 并以这种方式写入文件。