Создать таблицу PDF из строки HTML с кодировкой UTF-8
Я хочу создать таблицу PDF из строки HTML. Я могу создать эту таблицу, но вместо текста я получаю знаки вопроса. Вот мой код:
public class ExportReportsToPdf implements StreamSource {
private static final long serialVersionUID = 1L;
private ByteArrayOutputStream byteArrayOutputStream;
public static final String FILE_LOC = "C:/Users/KiKo/CasesWorkspace/case/Export.pdf";
private static final String CSS = ""
+ "table {text-align:center; margin-top:20px; border-collapse:collapse; border-spacing:0; border-width:1px;}"
+ "th {font-size:14px; font-weight:normal; padding:10px; border-style:solid; overflow:hidden; word-break:normal;}"
+ "td {padding:10px; border-style:solid; overflow:hidden; word-break:normal;}"
+ "table-header {font-weight:bold; background-color:#EAEAEA; color:#000000;}";
public void createReportPdf(String tableHtml, Integer type) throws IOException, DocumentException {
// step 1
Document document = new Document(PageSize.A4, 20, 20, 50, 20);
// step 2
PdfWriter.getInstance(document, new FileOutputStream(FILE_LOC));
// step 3
byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream);
if (type != null) {
writer.setPageEvent(new Watermark());
}
// step 4
document.open();
// step 5
document.add(getTable(tableHtml));
// step 6
document.close();
}
private PdfPTable getTable(String tableHtml) throws IOException {
// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(CSS.getBytes()));
cssResolver.addCss(cssFile);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser parser = new XMLParser(worker);
InputStream inputStream = new byteArrayInputStream(tableHtml.getBytes());
parser.parse(inputStream);
return (PdfPTable) elements.get(0);
}
private static class Watermark extends PdfPageEventHelper {
@Override
public void onEndPage(PdfWriter writer, Document document) {
try {
URL url = Thread.currentThread().getContextClassLoader().getResource("/images/memotemp.jpg");
Image background = Image.getInstance(url);
float width = document.getPageSize().getWidth();
float height = document.getPageSize().getHeight();
writer.getDirectContentUnder().addImage(background, width, 0, 0, height, 0, 0);
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
}
@Override
public InputStream getStream() {
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
}
}
Этот код работает, и я получаю это:
Я пытаюсь добавить UTF-8,
InputStream inputStream = new byteArrayInputStream(tableHtml.getBytes("UTF-8"));
Я хочу получить что-то вроде этого:
Я думаю, что проблема с кодировкой, но я не знаю, как решить эту ошибку. Какие-либо предложения...?
2 ответа
Чтобы получить байты из строки (Unicode) в некоторой кодировке, укажите ее, в противном случае используется системная кодировка по умолчанию.
tableHtml.getBytes(StandardCharsets.UTF_8)
В вашем случае, однако, "Windows-1251" кажется более подходящим, так как PDF, кажется, не использует UTF-8.
Возможно, исходная таблица HTML String была прочитана с неправильной кодировкой. Можете проверить это, если оно пришло из файла или базы данных.
Вам нужно сообщить iText, какую кодировку использовать, создав экземпляр класса BaseFont. Тогда в вашем document.add(getTable(tableHtml));
Вы можете добавить вызов к шрифту. Пример на http://itextpdf.com/examples/iia.php?id=199.
Я не могу сказать, как вы создаете таблицу, но класс PdfPTable
есть метод addCell(PdfCell)
и один конструктор для PdfCell
занимает Phrase
, Phrase
может быть построен с String
и Font
, Класс шрифта занимает BaseFont
в качестве аргумента конструктора.
Если вы посмотрите на Javadoc для iText, вы увидите, что различные классы принимают Font в качестве аргумента конструктора.