I am having the following issue with reporting to docx document. ‘\n’ or chr(10) characters automatically switches to spaces. I could not find how to solve this issue.
I am using SQL queries that return a string with possible new lines in it. But in docx report document new lines are shown as spaces.
Did this ever get resolved? I can see the issue and changes in github but it doesn’t look like the resolve was ever merged back into the main yarg and I don’t understand how to implement it by overriding the existing classes when it is embedded into the yarg jars.
It’s possible to solve this problem by providing a custom content inliner. Inliner’s job is to replace a text which contains new line characters with a set of <t> and <br> elements in the resulting DOCX document.
You’ll need to create a new inliner in your project:
import com.haulmont.yarg.exception.ReportFormattingException;
import com.haulmont.yarg.formatters.impl.doc.OfficeComponent;
import com.haulmont.yarg.formatters.impl.inline.ContentInliner;
import com.sun.star.text.XText;
import com.sun.star.text.XTextRange;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.SpreadsheetMLPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.SpreadsheetML.WorksheetPart;
import org.docx4j.wml.Br;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.R;
import org.docx4j.wml.Text;
import org.xlsx4j.sml.Cell;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Inliner splits the string value for lines and creates a pair of Text and Br elements for each line in text.
*/
public class ParagraphTextInliner implements ContentInliner {
public final static String REGULAR_EXPRESSION = "\\$\\{paragraphText\\}";
private Pattern tagPattern;
public ParagraphTextInliner() {
this.tagPattern = Pattern.compile(REGULAR_EXPRESSION, Pattern.CASE_INSENSITIVE);
}
@Override
public Pattern getTagPattern() {
return tagPattern;
}
@Override
public void inlineToXlsx(SpreadsheetMLPackage pkg, WorksheetPart worksheetPart, Cell newCell, Object paramValue, Matcher matcher) {
throw new UnsupportedOperationException("paragraphText format is not supported for XLSX");
}
@Override
public void inlineToDoc(OfficeComponent officeComponent, XTextRange textRange, XText destination, Object paramValue, Matcher paramsMatcher) throws Exception {
throw new UnsupportedOperationException("paragraphText format is not supported for DOC");
}
@Override
public void inlineToDocx(WordprocessingMLPackage wordPackage, Text text, Object paramValue, Matcher paramsMatcher) {
try {
if (paramValue instanceof String) {
String stringParamValue = (String) paramValue;
ObjectFactory factory = Context.getWmlObjectFactory();
String[] parts = stringParamValue.split("\n");
R parent = (R) text.getParent();
//spring text by \n and create a new <t> element followed by <br> for each part.
for (String part : parts) {
Text textPart = factory.createText();
textPart.setValue(part);
parent.getContent().add(textPart);
Br br = factory.createBr();
parent.getContent().add(br);
}
text.setValue("");
}
} catch (Exception e) {
throw new ReportFormattingException("An error occurred while inserting text with paragraphs to docx file", e);
}
}
@Override
public void inlineToXls(HSSFPatriarch patriarch, HSSFCell destination, Object paramValue, Matcher paramsMatcher) {
throw new UnsupportedOperationException("paragraphText format is not supported for XLS");
}
}
Create an inliners provider that registers this content inliner:
import com.haulmont.reports.libintegration.CubaInlinersProvider;
public class MyInlinersProvider extends CubaInlinersProvider {
public MyInlinersProvider() {
super();
addInliner(new ParagraphTextInliner());
}
}
In the spring.xml file register this inliners provider, it must replace the one provided by CUBA: