Spire.PDF is a professional PDF library applied to creating, writing, editing, handling and reading PDF files without any external dependencies. Get free and professional technical support for Spire.PDF for .NET, Java, Android, C++, Python.

Mon Nov 29, 2021 3:01 pm

I've an issue when trying to export a docx with table to PDF using saveToStream() on our linux server and JDK 13.0.2

An ArrayIndexOutOfBoundsException is generated.

Note : the same document is exported with success on our dev environment on Windows 10 64bits / JDK13

QuentinSup
 
Posts: 46
Joined: Mon Oct 18, 2021 9:18 am

Tue Nov 30, 2021 3:01 am

Hello,

Thanks for your inquiry!

I tested to save the document you provided to PDF stream on CentOS 7.9.2009 with the latest Spire.Office for java 4.11.3 under JDK 13.0.2, but still not reproduce your issue. Here I snapped my testing code and my runnable jar file. Please run the jar on your side.
Code: Select all
      String inputFile = "document.docx";

        //create word document
        FileInputStream stream1 = new FileInputStream(new File(inputFile));
        Document document = new Document();       
        document.loadFromStream(stream1, FileFormat.Auto);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        document.saveToStream(stream, FileFormat.PDF);
       
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream("topdf.pdf");
            fileOutputStream.write(stream.toByteArray());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

If the issue still exists, first, please make sure that you have all fonts you used in the document under the /usr/ahre/fonts folder of your Linux environment. And if the fonts are already here, please provide us with the information of your Linux environment (E.g. CentOS 7.9.2009). Thanks in advance.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Tue Nov 30, 2021 10:20 am

Hi,

Do you mean the issue could come from an unknow font system ? Don't Spire use a default font if there is not font available ?

The linux OS used is Debian Buster 10.
The fonts are installed into /usr/share/fonts and fonts cache have been reset with fc-cache -fv.

Here the fonts installed :

/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/CALIBRIL.TTF: Calibri,Calibri Light:style=Light,Regular
/usr/share/fonts/GOTHICI.TTF: Century Gothic:style=Italique,Cursiva,kurzíva,kursiv,Πλάγια,Italic,Kursivoitu,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/CALIBRI.TTF: Calibri:style=Regular
/usr/share/fonts/TIMESBI.TTF: Times New Roman:style=Gras Italique,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Bold Italic,Negrita Cursiva,Lihavoitu Kursivoi,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/TIMESI.TTF: Times New Roman:style=Italique,cursiva,kurzíva,kursiv,Πλάγια,Italic,Kursivoitu,Dőlt,Corsivo,Cursief,kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/ARIALNI.TTF: Arial,Arial Narrow:style=Italique,Narrow Italic,Cursiva,kurzíva,kursiv,Πλάγια,Italic,Kursivoitu,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,Etzana
/usr/share/fonts/ARIALN.TTF: Arial,Arial Narrow:style=Narrow,Normal,obyčejné,Standard,Κανονικά,Regular,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/TIMESBD.TTF: Times New Roman:style=Gras,Negreta,tučné,fed,Fett,Έντονα,Bold,Negrita,Lihavoitu,Félkövér,Grassetto,Vet,Halvfet,Pogrubiona,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/CALIBRII.TTF: Calibri:style=Italic
/usr/share/fonts/TAHOMABD.TTF: Tahoma:style=Gras,Negreta,tučné,fed,Fett,Έντονα,Bold,Negrita,Lihavoitu,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/ARLRDBD.TTF: Arial Rounded MT Bold:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/ARIAL.TTF: Arial:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/TAHOMA.TTF: Tahoma:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/CALIBRILI.TTF: Calibri,Calibri Light:style=Light Italic,Italic
/usr/share/fonts/CALIBRIB.TTF: Calibri:style=Bold
/usr/share/fonts/TIMES.TTF: Times New Roman:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,thường,Arrunta
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/GOTHICB.TTF: Century Gothic:style=Gras,Negreta,tučné,fed,Fett,Έντονα,Bold,Negrita,Lihavoitu,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/ARIALNB.TTF: Arial,Arial Narrow:style=Gras,Narrow Bold,Negreta,tučné,fed,Fett,Έντονα,Bold,Negrita,Lihavoitu,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/usr/share/fonts/ARIALUNI.TTF: Arial Unicode MS:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/GOTHICBI.TTF: Century Gothic:style=Gras Italique,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Bold Italic,Negrita Cursiva,Lihavoitu Kursivoi,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/CALIBRIZ.TTF: Calibri:style=Bold Italic
/usr/share/fonts/GOTHIC.TTF: Century Gothic:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/ARIALBI.TTF: Arial:style=Gras Italique,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Bold Italic,Negrita Cursiva,Lihavoitu Kursivoi,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,nghiêng đậm,Lodi etzana
/usr/share/fonts/ARIALI.TTF: Arial:style=Italique,Cursiva,kurzíva,kursiv,Πλάγια,Italic,Kursivoitu,Dőlt,Corsivo,Cursief,Kursywa,Itálico,Курсив,İtalik,Poševno,nghiêng,Etzana
/usr/share/fonts/ARIALNBI.TTF: Arial,Arial Narrow:style=Gras Italique,Narrow Bold Italic,Negreta cursiva,tučné kurzíva,fed kursiv,Fett Kursiv,Έντονα Πλάγια,Bold Italic,Negrita Cursiva,Lihavoitu Kursivoi,Félkövér dőlt,Grassetto Corsivo,Vet Cursief,Halvfet Kursiv,Pogrubiona kursywa,Negrito Itálico,Полужирный Курсив,Tučná kurzíva,Fet Kursiv,Kalın İtalik,Krepko poševno,Lodi etzana
/usr/share/fonts/ARIBLK.TTF: Arial,Arial Black:style=Black,Normal,obyčejné,Standard,Κανονικά,Regular,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/ARIALBD.TTF: Arial:style=Gras,Negreta,tučné,fed,Fett,Έντονα,Bold,Negrita,Lihavoitu,Félkövér,Grassetto,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,đậm,Lodia
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book

QuentinSup
 
Posts: 46
Joined: Mon Oct 18, 2021 9:18 am

Tue Nov 30, 2021 10:54 am

Hi,

Your runnable is working on our environment but please notice that we modify the document between and load and save actions.

here an extract of the code used to manipulate table and cells.

Code: Select all
import com.example.demo.CellTypeEnum;
import com.example.demo.CellValue;
import com.spire.doc.*;
import com.spire.doc.documents.BorderStyle;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.TextRange;
import com.spire.doc.formatting.CharacterFormat;

import java.awt.*;
import java.io.*;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

public class ExportPdfIndexOutOfBounds {

    protected static NumberFormat currencyFormater;
    protected static NumberFormat percentFormater;
    protected static NumberFormat currencyCompactFormater;
    protected static boolean formatCurrencyWithSymbol = true;
    protected static NumberFormat numberFormater;
    public static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

    {
        percentFormater = NumberFormat.getPercentInstance(Locale.FRANCE);
        percentFormater.setMaximumFractionDigits(2);
        currencyFormater = NumberFormat.getCurrencyInstance(Locale.FRANCE);
        currencyCompactFormater = DecimalFormat.getCompactNumberInstance(Locale.FRANCE, NumberFormat.Style.SHORT);
        numberFormater = NumberFormat.getNumberInstance(Locale.FRANCE);
        numberFormater.setMaximumFractionDigits(2);
    }

    public static void main(String[] args) throws Exception {

        String inputFile = "document.docx";

        //create word document
        FileInputStream stream1 = new FileInputStream(new File(inputFile));
        Document document = new Document();
        document.loadFromStream(stream1, FileFormat.Auto);

        Map<String, TagValue<?>> rows = new HashMap<>();

        rows.put("period", new TagValue<>(List.of("1", "2", "3", "Total"), TagValueTypeEnum.ROW));
        rows.put("rentAmount", new TagValue<>(List.of("1000", "2000", "3000", "6000"), TagValueTypeEnum.ROW));
        /**
         * @TODO More example
         */
        fillTables(rows, document);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        document.saveToStream(stream, FileFormat.PDF);

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream("topdf.pdf");
            fileOutputStream.write(stream.toByteArray());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Traite les tableaux dynamiques d'un document WORD
     *
     * @param mapList values
     * @param doc     document
     */
    public static void fillTables(Map<String, TagValue<?>> mapList, Document doc) {
        if (doc.getSections() != null && doc.getSections().getCount() > 0) {
            for (Section section : (Iterable<Section>) doc.getSections()) {
                if (section.getTables() != null && section.getTables().getCount() > 0) {
                    for (int i = 0; i < section.getTables().getCount(); i++) {
                        int maxColumnCount = fillTable(mapList, section.getTables().get(i));
                        if (maxColumnCount > 0) {
                            formatTable(section.getTables().get(i), maxColumnCount);
                        }
                    }
                }
            }
        }
    }

    /**
     * Complète un tableau WORD par les valeurs correspondantes de la liste formatée et supprime les tags traités du référentiel de tags si non null
     *
     * @param map     values
     * @param table   table
     */
    private static int fillTable(Map<String, TagValue<?>> map, Table table) {
        boolean isReplaced;
        int maxColumnCount = 0;

        // replace values from map list
        for (Object o : table.getRows()) {
            final TableRow row = ((TableRow) o);
            for (Map.Entry<String, TagValue<?>> entry : map.entrySet()) {
                final String formatedKey = "${" + entry.getKey() + "[n]}";
                if (row.getCells().getCount() > 0) {
                    if (row.getCells().get(row.getCells().getCount() - 1).getParagraphs().get(0).getText()
                            .contains(formatedKey))
                    {
                        isReplaced = false;
                        final List<?> values = (List<?>) entry.getValue().getValue();
                        maxColumnCount = Math.max(values.size(), maxColumnCount);
                        for (Object v : values) {
                            final String value = formatValue(mapToTagValue(v));
                            if (!isReplaced) {
                                row.getCells().get(row.getCells().getCount() - 1).getFirstParagraph()
                                        .replace(formatedKey, value, true, true);
                                isReplaced = true;
                            } else {
                                row.addCell().addParagraph().appendText(value);
                            }
                        }
                    }
                }
            }
        }
        return maxColumnCount;
    }

    /**
     * return appropriate representation oif tag value depending on type
     *
     * @param o Object value
     */
    protected static TagValue<?> mapToTagValue(Object o) {

        if (o instanceof TagValue) {
            return (TagValue<?>) o;
        }

        if (o instanceof CellValue) {
            final CellValue<?> cellValue = (CellValue<?>) o;
            if (cellValue.getType() == CellTypeEnum.CURRENCY) {
                return new TagValue<>(cellValue.getValue(), TagValueTypeEnum.CURRENCY);
            }
            if (cellValue.getType() == CellTypeEnum.CURRENCY_COMPACT) {
                return new TagValue<>(cellValue.getValue(), TagValueTypeEnum.CURRENCY_COMPACT);
            }
            if (cellValue.getType() == CellTypeEnum.NUMBER) {
                return new TagValue<>(cellValue.getValue(), TagValueTypeEnum.NUMBER);
            }
            if (cellValue.getType() == CellTypeEnum.PERCENT) {
                return new TagValue<>(cellValue.getValue(), TagValueTypeEnum.PERCENT);
            }
            if (cellValue.getType() == CellTypeEnum.DATE) {
                return new TagValue<>(cellValue.getValue(), TagValueTypeEnum.DATE);
            }
        }

        if (o instanceof Long || o instanceof Integer || o instanceof Float) {
            return new TagValue<>(o, TagValueTypeEnum.NUMBER);
        }

        if (o instanceof Double) {
            return new TagValue<>(o, TagValueTypeEnum.PERCENT);
        }

        if (o instanceof List) {
            return new TagValue<>(((List<?>) o).stream().map(ExportPdfIndexOutOfBounds::mapToTagValue).collect(Collectors.toList()),
                    TagValueTypeEnum.LIST);
        }

        return new TagValue<>(o, TagValueTypeEnum.TEXT);

    }

    public enum TagValueTypeEnum {
        TEXT, CURRENCY, CURRENCY_COMPACT, NUMBER, PERCENT, DATE, IMAGE_BYTE, IMAGE_BASE64, IMAGE_PATH, MERGE_FIELD, CHART, LIST, ROW
    }

    public static class TagValue<T> {
        private T value;
        private TagValueTypeEnum type = TagValueTypeEnum.TEXT;

        public TagValue(T value) {
            this.value = value;
        }

        public TagValue(T value, TagValueTypeEnum type) {
            this.value = value;
            this.type = type;
        }

        public boolean isPrimitive() {
            return type.equals(TagValueTypeEnum.TEXT) || type.equals(TagValueTypeEnum.DATE) || type.equals(
                    TagValueTypeEnum.CURRENCY) || type.equals(TagValueTypeEnum.CURRENCY_COMPACT) || type.equals(
                    TagValueTypeEnum.NUMBER) || type.equals(TagValueTypeEnum.PERCENT);
        }

        public T getValue() {
            return value;
        }

        public void setValue(T value) {
            this.value = value;
        }

        public TagValueTypeEnum getType() {
            return type;
        }

        public void setType(TagValueTypeEnum type) {
            this.type = type;
        }
    }

    /**
     * Mise en forme des lignes d'un tableau WORD
     *
     * @param table          table
     * @param maxColumnCount max column count
     */
    private static void formatTable(Table table, int maxColumnCount) {
        TableRow row;
        TableCell cell, firstCell;
        Paragraph cellParagraph, firstParagraph;
        TextRange cellText;
        Color borderColor;

        // format table rows
        final int totalColumnCount = maxColumnCount;
        int columnCount;
        int rowCount = 1;
        final PreferredWidth tableWidth = new PreferredWidth(WidthType.Percentage, (short) 100);
        table.setPreferredWidth(tableWidth);
        table.getTableFormat().getPaddings().setLeft(5);
        table.getTableFormat().getPaddings().setRight(5);
        float columnWidth =
                (table.getWidth() - table.getFirstRow().getCells().get(0).getWidth()) / (totalColumnCount + 1);
        table.setDefaultColumnWidth(columnWidth);
        for (Object o1 : table.getRows()) {
            row = ((TableRow) o1);

            while (row.getCells().getCount() <= totalColumnCount) {
                row.addCell().addParagraph().appendText("");
            }

            firstCell = row.getCells().get(1);

            firstParagraph = (Paragraph) firstCell.getFirstParagraph();
            final CharacterFormat characterFormatModel = firstParagraph.getChildObjects().getCount() > 0 ?
                    ((TextRange) firstParagraph.getChildObjects().get(0)).getCharacterFormat() :
                    firstParagraph.getBreakCharacterFormat();

            columnCount = 1;
            for (Object o2 : row.getCells()) {

                if (columnCount == 1) {
                    columnCount++;
                    continue;
                }

                borderColor = rowCount == 1 ? Color.WHITE : Color.BLACK;
                cell = (TableCell) o2;

                // TODO -> appliquer le format de la première ligne cell et paragraph à la dernière colonne de chaque ligne
                // condition : rowCount != 2 && columnCount == row.getCells().getCount()

                if (columnCount == totalColumnCount + 1) {
                    cell.setCellWidth((float) (columnWidth * 1.20), CellWidthType.Point);
                } else {
                    cell.setCellWidth(columnWidth, CellWidthType.Point);
                }

                // cell format
                cell.getCellFormat().setBackColor(firstCell.getCellFormat().getBackColor());
                cell.getCellFormat().setVerticalAlignment(firstCell.getCellFormat().getVerticalAlignment());
                cell.getCellFormat().setVerticalMerge(firstCell.getCellFormat().getVerticalMerge());
                cell.getCellFormat().setTextWrap(false);

                // right border all 5 year period ; no border for line 2
                cell.getCellFormat().getBorders().getBottom()
                        .setBorderType(firstCell.getCellFormat().getBorders().getBottom().getBorderType());
                cell.getCellFormat().getBorders().getTop()
                        .setBorderType(firstCell.getCellFormat().getBorders().getTop().getBorderType());
                cell.getCellFormat().getBorders().getLeft().setBorderType(
                        rowCount != 2 && columnCount <= 2 ? BorderStyle.Basic_Thin_Lines : BorderStyle.Cleared);
                cell.getCellFormat().getBorders().getRight().setBorderType(
                        rowCount != 2 && ((columnCount - 1) % 5 == 0 || columnCount == row.getCells().getCount()) ?
                                BorderStyle.Basic_Thin_Lines : BorderStyle.Cleared);
                cell.getCellFormat().getBorders().getRight().setColor(borderColor);
                cell.getCellFormat().getBorders().getLeft().setColor(borderColor);

                // paragraph format
                cellParagraph = cell.getParagraphs().getCount() > 0 ? (Paragraph) cell.getFirstParagraph() :
                        cell.addParagraph();

                cellParagraph.applyStyle(firstParagraph.getStyleName());
                cellParagraph.getFormat().setHorizontalAlignment(firstParagraph.getFormat().getHorizontalAlignment());
                cellParagraph.getFormat().setTextAlignment(firstParagraph.getFormat().getTextAlignment());
                cellParagraph.getFormat().setBeforeSpacing(firstParagraph.getFormat().getBeforeSpacing());
                cellParagraph.getFormat().setAfterSpacing(firstParagraph.getFormat().getAfterSpacing());
                cellText = cellParagraph.getChildObjects().getCount() > 0 ?
                        (TextRange) cellParagraph.getChildObjects().get(0) : cellParagraph.appendText("");

                if (characterFormatModel != null) {
                    cellText.getCharacterFormat().setTextColor(characterFormatModel.getTextColor());
                    cellText.getCharacterFormat().setFontName(characterFormatModel.getFontName());
                    cellText.getCharacterFormat().setFontSize(characterFormatModel.getFontSize());
                    cellText.getCharacterFormat().setBold(characterFormatModel.getBold());
                    cellText.getCharacterFormat().setUnderlineStyle(characterFormatModel.getUnderlineStyle());
                }

                if (cellText.getText().isBlank()) {
                    cellText.getCharacterFormat().setTextColor(Color.WHITE);
                    // Mandatory to have a character (not space) for the style to be applied correctly
                    cellText.setText("-");
                    cellText.getCharacterFormat().setFontSize(1);
                }

                columnCount++;
            }
            //row.setHeight(initialRowHeight);

            rowCount++;
        }
    }

    /**
     * Format tag value ; if null, return ""
     *
     * @param tag value to format
     */
    protected static String formatValue(TagValue<?> tag) {
        Object tagValue = tag.getValue() != null ? tag.getValue() : null;
        if (tagValue != null) {
            if (TagValueTypeEnum.CURRENCY == tag.getType()) {
                tagValue = currencyFormat(String.valueOf(tagValue), formatCurrencyWithSymbol);
            } else if (TagValueTypeEnum.CURRENCY_COMPACT == tag.getType()) {
                tagValue = currencyCompactFormat(String.valueOf(tagValue), formatCurrencyWithSymbol);
            } else if (TagValueTypeEnum.NUMBER == tag.getType()) {
                tagValue = numberFormat(tagValue);
            } else if (TagValueTypeEnum.PERCENT == tag.getType()) {
                tagValue = percentFormat(tagValue);
            } else if (TagValueTypeEnum.DATE == tag.getType()) {
                assert tagValue instanceof Date;
                tagValue = dateFormat.format((Date) tagValue);
            }
        }
        return getFixedValue(tagValue);
    }

    /**
     * Return string value with fixed chars
     *
     * @param tagValue the object
     * @return the fixed string value
     */
    protected static String getFixedValue(Object tagValue) {
        return tagValue == null ? "" :
                (tagValue instanceof String ? (String) tagValue : tagValue.toString()).replace((char) 8239, (char) 160);
    }

    /**
     * Formattage du prix
     *
     * @param amount         value to format
     * @param currencySymbol boolean
     * @return String
     */
    protected static String currencyFormat(String amount, boolean currencySymbol) {
        return currencyFormat(amount, currencySymbol, currencyFormater);
    }

    /**
     * Formattage du prix
     *
     * @param amount         value to format
     * @param currencySymbol boolean
     * @return String
     */
    protected static String currencyCompactFormat(String amount, boolean currencySymbol) {

        NumberFormat numberFormat;
        if (isNullOrZeroValue(amount)) {
            numberFormat = currencyFormater;
        } else {
            final double value = Double.parseDouble(amount);
            if (value > -1000000. && value < 1000000.) {
                numberFormat = currencyFormater;
            } else {
                numberFormat = (NumberFormat) currencyCompactFormater.clone();
                double absValue = Math.abs(value);
                while (absValue > 1000) {
                    double r = absValue % 1000;
                    if (r != 0) {
                        numberFormat.setMinimumFractionDigits(String.valueOf(r).length());
                        break;
                    }
                    absValue = absValue / 1000;
                }
            }
        }

        String value = currencyFormat(amount, false, numberFormat);
        if(currencySymbol) {
            value = value.concat(Currency.getInstance(Locale.FRANCE).getSymbol());
        }
        return value;
    }

    public static boolean isNullOrZeroValue(String value) {
        return (value == null || "".equals(value) || "null".equals(value));
    }

    /**
     * Formattage du prix
     *
     * @param amount         value to format
     * @param currencySymbol boolean
     * @return String
     */
    protected static String currencyFormat(String amount, boolean currencySymbol, final NumberFormat numberFormat) {

        NumberFormat format = numberFormat;

        if (isNullOrZeroValue(amount)) {
            return format.format(0);
        }

        if (!currencySymbol) {
            if (format instanceof DecimalFormat) {
                final DecimalFormat decimalFormat = (DecimalFormat) format.clone();
                final DecimalFormatSymbols decimalFormatSymbols = decimalFormat.getDecimalFormatSymbols();
                decimalFormatSymbols.setCurrencySymbol("");
                decimalFormat.setDecimalFormatSymbols(decimalFormatSymbols);
                format = decimalFormat;
            }
        }

        return format.format(Double.parseDouble(amount));

    }

    /**
     * Formattage d'un nombre
     *
     * @param number value to format
     * @return String
     */
    protected static String numberFormat(Object number) {
        if (number == null || "".equals(number) || "null".equals(number)) {
            return numberFormater.format(0);
        }
        return numberFormater.format(number);
    }

    /**
     * Formattage d'un nombre
     *
     * @param number value to format
     * @return String
     */
    protected static String percentFormat(Object number) {
        if (number == null || "".equals(number) || "null".equals(number)) {
            return percentFormater.format(0);
        }
        return percentFormater.format(number);
    }

}


QuentinSup
 
Posts: 46
Joined: Mon Oct 18, 2021 9:18 am

Tue Nov 30, 2021 8:59 pm

This issue is very critical for us : we need it to be solved to launch our product !

The problem is due to the table generation : I can generate the final document if I remove the manipulated tables from the template docx, but I don't understand what exactly, and why it is working on a dev environment (Windows 10 Pro 64 bits JDK13), and not on the production environment (Debian Buster10, JDK13), and only when exporting to PDF...

I use a similar manipulation with tables inside a PPTX template, and this issue not appears...

QuentinSup
 
Posts: 46
Joined: Mon Oct 18, 2021 9:18 am

Wed Dec 01, 2021 5:38 am

Hello,

Thanks for sharing more information!

I have reproduced your issue and logged it in our issue tracking system with the ticket SPIREDOC-7048 for further investigation.

We will let you know if there is any update. Sorry for the inconvenience caused.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Wed Dec 01, 2021 8:33 am

Hi,

Thanks for your reply, but I need a workaround as soon as possible !
Can you explain what is the problem and if we can change something to move on and launch our product please !

QuentinSup
 
Posts: 46
Joined: Mon Oct 18, 2021 9:18 am

Wed Dec 01, 2021 8:51 am

Hello,

Thanks for your feedback!

I noticed your situation and informed it to our development team. Sorry that I cannot tell you the reason of your issue now since our development team is still investigating on your issues.

Anyway, I urged and requested our development team to share any possible ETA at their earliest, once there is any good news, we will notify you immediately. Sorry for the inconvenience caused.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Tue Jan 25, 2022 10:12 am

Hello,

Thanks for your patience!

Glad to inform you that we just released Spire.Office for Java 5.1.5 Version:5.1.5 which fixes the issue SPIREDOC-7048.

Please download the fix version from the following links to test.

Website link: https://www.e-iceblue.com/Download/office-for-java.html

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Wed Feb 09, 2022 7:46 am

Hello,

Hope you are doing well!

Has the issue been solved now? Could you please give us some feedback at your convenience?

Thanks in advance.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Return to Spire.PDF