PDF file conversion from Word file fails on AWS Lambda

Hi
I am trying to convert word to pdf and there are some unusual fonts being used. Due to which failure is happening on AWS lambda. When I am testing locally its working fine.

Can you direct me to a fix to make it workable on AWS Lambda too?
How to provide font files if its missing, I am not sure if it trigger any errors or what?

I am attaching the files which are failing the conversion on LAMBDA only

using (var docFileStream =
            await s3FileService.GetDownloadFileStreamAsync(
                new AmazonS3FileRequest
                {
                    BucketName = documentFile.BucketName,
                    Key = GetS3FileKey(documentFile)
                }).ConfigureAwait(false))
        {
            Aspose.Words.Document document = new Aspose.Words.Document(docFileStream);
            document.Save(result.ResultStream, Aspose.Words.SaveFormat.Pdf);

WordFiles.zip (23.0 KB)

@AmnaNoor

Please note that Aspose.Words requires TrueType fonts when rendering document to fixed-page formats (JPEG, PNG, PDF or XPS). You need to install fonts that are used in your document on the machine where you are converting documents to PDF. Please refer to the following articles:

Using TrueType Fonts
Manipulating and Substitution TrueType Fonts

If you still face problem, please ZIP and attach your input Word document along with problematic and expected output PDF here for testing. We will investigate the issue and provide you more information on it.

@tahir.manzoor Its the issue on Lambda AWS, where I cannot install these fonts. I have already attached document in word format

Now attached the one sample wrong pdf result which is happening on lambda only
print (1).pdf (14.8 KB)

Also how to identify if proper conversion is not placed? So I can write alternate code to handle

@AmnaNoor

Please read the following article about integrating Aspose.Words in AWS Lambda.
Aspose.Words Integration in AWS Lambda

@tahir.manzoor I am following the article but I cannot add all fonts to S3, I only need to use fonts if its not available in default.
How can I manage to add both SystemFonts and S3Fonts, so it can use all?

 FontSettings fontSettings = FontSettings.DefaultInstance;
            fontSettings.SetFontsSources(new FontSourceBase[]
             {
                new SystemFontSource(),
                Task.Run(async () => await s3FontService.GetS3FontSources(documentFile.BucketName, "Fonts")).Result
             });

I am trying this but both have different return type, can you help here?

@AmnaNoor

Please make sure that you have created a “Fonts” folder in your S3 bucket and uploaded the fonts there. You can use the code example shared in the following article to get the correct output.

How to Use Fonts Stored in S3 storage in AWS Lambda

I am asking, how to use system fonts and s3 storage fonts combine?
The article you provided doesn’t have this information

Please check the members of SystemFontSource class from here:

However, we have logged your requirement as WORDSNET-21849 in our issue tracking system. We will get back to you as soon as there is an update available on it.

1 Like

@AmnaNoor You can modify GetS3FontSources method to make it return array of FontSourceBase objects. And put additional font sources before adding S3 font sources. Please see the following modified method:

/// <summary>
/// Lists fonts in the S3 folder and creates S3FontSource for each of them.
/// </summary>
private static async Task<FontSourceBase[]> GetS3FontSources(IAmazonS3 client, string bucketName, string fontsFolderKey)
{
    ListObjectsV2Request request = new ListObjectsV2Request()
    {
        BucketName = bucketName,
        Prefix = fontsFolderKey
    };

    List<FontSourceBase> fontList = new List<FontSourceBase>();
    // Add SystemFontSource as the first source to look for fonts in.
    fontList.Add(new SystemFontSource());

    ListObjectsV2Response response;
    do
    {
        // Note to perform this operation you need to have permission to perform the s3:Listbucket.
        response = await client.ListObjectsV2Async(request);
        // Process the response.
        foreach (S3Object entry in response.S3Objects)
        {
            // Skip folder.
            if (entry.Key.EndsWith("/"))
                continue;
            fontList.Add(new S3FontSource(client, bucketName, entry.Key));
        }

        request.ContinuationToken = response.NextContinuationToken;
    } while (response.IsTruncated);
            
    return fontList.ToArray();
}

@alexey.noskov Thank you for sharing this. This is exactly what I was looking for. It worked.