Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Thu Jan 05, 2023 9:25 am

I have a word document with a non standard font in it, when I try to save it as a pdf file the font changes. I would like to keep to original font used in the word document I tried setting the private font paths, this seems to work when running the project in Intellij but not when the jar is ran.

I have the following code

Code: Select all
Document doc = new Document();
doc.loadFromFile(inputPath);
ToPdfParameterList ppl = new ToPdfParameterList();
ppl.setPrivateFontPaths(getPrivateFontPaths());
ppl.isEmbeddedAllFonts(true);
ppl.setMemoryOptimization(true);
ppl.setDisableLink(false);
doc.setJPEGQuality(80);
doc.saveToFile(outputPath, ppl);
doc.close();


private List<PrivateFontPath> getPrivateFontPaths() {
    //String fontLocation=Objects.requireNonNull(this.getClass().getClassLoader().getResource("fonts")).toString();
    String fontLocation="..\\..\\..\\..\\..\\..\\..\\fonts\\";
    List<PrivateFontPath> privateFontPaths = new ArrayList<>();

    String fontName = "myfont";
    privateFontPaths.add(new PrivateFontPath(fontName, PdfFontStyle.Bold.getValue(), fontLocation + "myfont.otf"));

    return privateFontPaths;
}


I believe the issue is with location of the fonts when it is packages as a jar, as I want the otf file embedded in the jar so the fonts will work everywhere the jar is run.

I tried multiple approaches using a relative path, getting the location of the resource in code and using the absolute path where I removed the `file:` prefix, used with prefix.

So how can I add a custom font that is packaged inside the jar?

Robbenpr
 
Posts: 4
Joined: Thu Jan 05, 2023 7:24 am

Fri Jan 06, 2023 12:43 pm

Hi,

Thanks for your inquiry.
I did some tests and reproduced the issue you mentioned, I have logged this issue into our bug tracking system with the ticket number SPIREDOC-8962. Our developers will investigate and fix it. Sorry for the inconvenience caused, once the issue is fixed, I will inform you asap.

Sincerely,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Fri Jan 13, 2023 10:25 am

Triste.Dai wrote:Hi,

Thanks for your inquiry.
I did some tests and reproduced the issue you mentioned, I have logged this issue into our bug tracking system with the ticket number SPIREDOC-8962. Our developers will investigate and fix it. Sorry for the inconvenience caused, once the issue is fixed, I will inform you asap.

Sincerely,
Triste
E-iceblue support team


Hi,

Is there any update or timeline available?

Robbenpr
 
Posts: 4
Joined: Thu Jan 05, 2023 7:24 am

Mon Jan 16, 2023 9:32 am

Hi,

Thanks for your following-up.
Sorry for the late reply due to the weekend. This issue has not been solved yet, our developers are working hard on it. I have urged them to speed up fixing this issue. Sorry for the inconvenience caused. Once the issue is fixed, I will inform you as soon as possible. Thanks for your understanding.

Sincerely,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Wed Jan 18, 2023 7:50 am

Hi,

Thanks for your patience!
According to our developers’ feedback, when you package the project, the font path is changed and not accessible, so when you run the jar, the font path is not correct and the method “ToPdfParameterList.setPrivateFontPaths()” will not work.
You can access the file in the jar by calling method ClassLoader.getResourceAsStream(), this will return an InputStream instance of the file, but the method needs a path, instead of a stream. You can write the stream to a file where the jar file is located, and then refer its path in the java code. See following code for reference.
Code: Select all
        private static List<PrivateFontPath> getPrivateFontPaths() throws IOException {
        InputStream is = null;

        try{
            // src/main/resources/fontpath
            is = Test.class.getClassLoader().getResourceAsStream("fontpath/myfont.ttf");
            Files.copy(is, Paths.get("myfont.ttf"));
        }catch (IOException e){
            is.close();
        }

        List<PrivateFontPath> privateFontPaths = new ArrayList<>();
        String fontName = "myfont.ttf";
        privateFontPaths.add(new PrivateFontPath(fontName, PdfFontStyle.Bold.getValue(),  "myfont.ttf"));
        return privateFontPaths;
    }

There is no other alternative solution at present. Maybe we can add the stream as an argument to the constructor of PrivateFontPath, so I added it into our upgrade list with the ticket number SPIREDOC-9004, once it is implemented, I will inform you.
You can try the code I provided or create a folder where the jar is located and put your fonts in it. If you have further questions, just feel free to contact us.

Sincerely,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Wed Jan 18, 2023 8:23 am

Hi,

Thank you for your response, we will use the workaround you proposed for now.

Adding the inputsteam to the constructor would be great, this way we can also check in the code if the file is found.

If possible I would also like an error or warning message if you are unable to find the font specified by the fontLocation, this would make it easier to find issues with the PrivateFontPaths.

Robbenpr
 
Posts: 4
Joined: Thu Jan 05, 2023 7:24 am

Thu Jan 19, 2023 10:02 am

Hi,

Thanks for your feedback.
When the specific font file is not found, our products will find some relate fonts for replacement, to keep the format of the file organized. I have added your idea into our upgrade list with the ticket number SPIREDOC-9006, once it is implemented, I will inform you. Thanks for your suggestion.
If you have other questions related to our products, just feel free to contact us.

Sincerely,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Fri Feb 10, 2023 9:37 am

Hi,

I have another suggestion related to SPIREDOC-9004 (possibility to use an InputStream instead of a String).

When doing a mailmerge you need to add the path to an xml file:
Code: Select all
MailMerge mailMerge = document.getMailMerge();
mailMerge.executeWidthRegion(pathToXml);


It would also be nice if we can use an InputStream here instead of a String which contains the path, this would avoid too much file IO on the system.

Thanks in advance.

Robbenpr
 
Posts: 4
Joined: Thu Jan 05, 2023 7:24 am

Mon Feb 13, 2023 8:04 am

Hi,

Thanks for your feedback.
I have recorded your suggestion into our system with the ticket number SPIREDOC-9054, our developers will do an evaluation, once it is implemented, I will keep you informed. Thanks for your suggestion!

Sincerely,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Fri Jun 09, 2023 7:45 am

Hi,

Thanks for your patience.
Glad to inform you that we just released Spire.Office for Java 8.6.0, which has implemented the new feature SPIREDOC-9054: the mail merge function supports loading files from streams. See the following code for reference.
Code: Select all
document.getMailMerge().executeWidthRegion(InputStream stream);

Please download from the following links and have a test.

Website: https://www.e-iceblue.com/Download/office-for-java.html
Maven:
Code: Select all
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.office</artifactId>
        <version>8.6.0</version>
    </dependency>
</dependencies>


Best regards,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Tue Jun 27, 2023 1:22 pm

Hi,

I tried the new feature SPIREDOC-9054: mail merge function supports loading files from streams.
Code: Select all
String xmlString = "<xml>" + XML.toString(mergeItem.getDataSourceJSON(), "root") + "</xml>";
InputStream inputStream= new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8));

MailMerge mailMerge = document.getMailMerge();
mailMerge.executeWidthRegion(inputStream);


I am receiving the correct file, but all the merge fields are empty.
When I use the mailMerge.executeWidthRegion(pathToXml); everything is working fine.

Thanks in advance.

fvangene
 
Posts: 2
Joined: Wed Jun 14, 2023 11:00 am

Wed Jun 28, 2023 3:24 am

fvangene wrote:Hi,

I tried the new feature SPIREDOC-9054: mail merge function supports loading files from streams.
Code: Select all
String xmlString = "<xml>" + XML.toString(mergeItem.getDataSourceJSON(), "root") + "</xml>";
InputStream inputStream= new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8));

MailMerge mailMerge = document.getMailMerge();
mailMerge.executeWidthRegion(inputStream);


I am receiving the correct file, but all the merge fields are empty.
When I use the mailMerge.executeWidthRegion(pathToXml); everything is working fine.

Thanks in advance.


Hi,

Thanks for your feedback.
Could you please share us with your document and xml file? So that we can investigate further and work out a solution for you. You can share them with us via email ([email protected]) or attach them here. Thanks for your assistance.

Best regards,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Wed Jun 28, 2023 10:13 am

Hi

I appreciate the quick response. My apologies for the inconvenience caused; it was an error on my part. Upon attempting to send you the XML file, I noticed that something was incorrect.

I solved it:
Code: Select all
JSONObject jsonObject = new JSONObject(mergeItem.getDataSourceJSON());
String xmlString = "<xml>" + XML.toString(jsonObject, "root") + "</xml>";
InputStream inputStream= new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8));

MailMerge mailMerge = document.getMailMerge();
mailMerge.executeWidthRegion(inputStream);


Thank you.

fvangene
 
Posts: 2
Joined: Wed Jun 14, 2023 11:00 am

Thu Jun 29, 2023 1:21 am

fvangene wrote:Hi

I appreciate the quick response. My apologies for the inconvenience caused; it was an error on my part. Upon attempting to send you the XML file, I noticed that something was incorrect.

I solved it:
Code: Select all
JSONObject jsonObject = new JSONObject(mergeItem.getDataSourceJSON());
String xmlString = "<xml>" + XML.toString(jsonObject, "root") + "</xml>";
InputStream inputStream= new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8));

MailMerge mailMerge = document.getMailMerge();
mailMerge.executeWidthRegion(inputStream);


Thank you.


Hi,

Thanks for your feedback.
We are delighted to hear that you have solved this issue. If you have any other questions, just feel free to contact us.

Have a nice day!

Best regards,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Wed Jul 19, 2023 9:05 am

Hi Robbenpr,

Thanks for your patience.
Glad to inform you that we just released Spire.Office for Java 8.7.2, which has implemented the new feature SPIREDOC-9004, The constructor of PrivateFontPath now supports passing a stream as an argument, and it can also be set using the setter method. Please refer to the following code snippet as an example:

Code: Select all
// constructor
PrivateFontPath(String fontName,InputStream fontStream);
PrivateFontPath(String fontName,int fontStyle,InputStream fontStream);

// setter and getter
setFontStream(InputStream value);
getFontStream();


Please download from the following link or install from Maven and have a test.
Website link: https://www.e-iceblue.com/Download/office-for-java.html
Maven:
Code: Select all
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.office</artifactId>
        <version>8.7.2</version>
    </dependency>
</dependencies>


Best regards,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Return to Spire.Doc