Как я могу гарантировать, что смайлы отображаются правильно в именах файлов и именах пользователей?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу гарантировать, что смайлы отображаются правильно в именах файлов и именах пользователей?

Сообщение Anonymous »

Я использую iText для обработки различных шрифтов и смайлов, но смайлы не отображаются должным образом. Вместо этого они полностью удаляются.Это мои зависимости

Код: Выделить всё

com.itextpdf
kernel
7.0.4


com.itextpdf
io
7.0.4


com.itextpdf
layout
7.0.4


com.itextpdf
forms
7.0.4


com.itextpdf
pdfa
7.0.4


com.itextpdf
pdftest
7.0.4

Код: Выделить всё

public class ChatTranscriptServiceImpl implements ChatTranscriptService {

private final ChatParticipantClient chatParticipantClient;

private static final float MARGIN_X = 50;
private static final float MARGIN_Y = 50;
private static final float FONT_SIZE = 12;
private static final float LINE_HEIGHT = 1.5f * FONT_SIZE;

private List  messages;
private String ticketNumber;
private String issuedTime;
private String closedTime;
private String clientWhatsAppNumber;
private String customerWhatsAppNumber;
private String agentName;
private String customerName;
private String lastOutgoingMessageTime;
private String fileName;

private PDFont emojiFont;
private PDFont fallbackFont;
private static final PDFont BOLD_FONT = PDType1Font.HELVETICA_BOLD;
private static final PDFont ITALIC_FONT = PDType1Font.TIMES_ITALIC;
private static final PDFont COURIER_FONT = PDType1Font.COURIER;

private static final String NORMAL_FONT = "normal";

public ChatTranscriptServiceImpl(ChatParticipantClient chatParticipantClient) {
this.chatParticipantClient = chatParticipantClient;
}

@Override
public ChatTranscriptResponse downloadChatTranscript(String chatParticipantId) {
this.messages = chatParticipantClient.getMessagesByChatParticipant(chatParticipantId);
byte[] pdfBytes = processMessages();

ChatTranscriptResponse response = new ChatTranscriptResponse();
response.setPdfBytes(pdfBytes);
response.setFilename(fileName);
return response;
}

private byte[] processMessages() {
Pattern ticketNumberPattern = Pattern.compile("Your (?:previous )?ticket number is (.*?) please retain the ticket number to reference this chat.", Pattern.DOTALL);
Pattern ratingMessagePattern = Pattern.compile("Please rate our service.");

for (Message message : this.messages) {
processTicketNumber(ticketNumberPattern, message);
processOutgoingMessage(message);
processRatingMessage(ratingMessagePattern, message);
extractWhatsAppNumbers(message);
}

return finalizeTranscript();
}

private void processTicketNumber(Pattern pattern, Message message) {
String text = message.getText();

if (text != null) {
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
ticketNumber = matcher.group(1).trim();
issuedTime = formatDateTime(message.getCreatedTime());
} else if (issuedTime == null) {
issuedTime = formatDateTime(message.getCreatedTime());
}
} else if (issuedTime == null) {
issuedTime = formatDateTime(message.getCreatedTime());
}
}

private void processOutgoingMessage(Message message) {
if (Pl4ChatMessageDirection.OUTGOING.equals(message.getDirection())) {
lastOutgoingMessageTime = formatDateTime(message.getCreatedTime());

if (message.getAgent() != null) {
agentName = getAgentName(message.getAgent());
} else {
agentName = "Bot";
}

if (message.getChatParticipant() != null) {
customerName = getCustomerName(message.getChatParticipant());
}
}
}

private void processRatingMessage(Pattern pattern, Message message) {
Matcher matcher = pattern.matcher(message.getText());
if (matcher.find()) {
closedTime = formatDateTime(message.getCreatedTime());
} else if (message.getChatParticipant() != null && message.getChatParticipant().isConversationClosed()) {
closedTime = lastOutgoingMessageTime != null ? lastOutgoingMessageTime : "Open";
} else {
closedTime = "Open";
}
}

private void extractWhatsAppNumbers(Message message) {
if (clientWhatsAppNumber == null && message.getChatParticipant() != null && message.getChatParticipant().getWhatsAppClientNumber() != null) {
clientWhatsAppNumber = message.getChatParticipant().getWhatsAppClientNumber();
}

if (customerWhatsAppNumber == null && message.getChatParticipant() != null && message.getChatParticipant().getPhoneNumber() != null) {
customerWhatsAppNumber = message.getChatParticipant().getPhoneNumber();
}
}

private String getAgentName(SystemUser agent) {
if (agent.getFirstName() != null && agent.getLastName() != null) {
return agent.getFirstName() + " "  + agent.getLastName();
} else if (agent.getFirstName() != null) {
return agent.getFirstName();
} else if (agent.getLastName() != null) {
return agent.getLastName();
}
return "Bot";
}

private String getCustomerName(ChatParticipant participant) {
if (participant.getFullName() != null) {
return participant.getFullName();
} else if (participant.getFirstName() != null && participant.getLastName() != null) {
return participant.getFirstName() + " " + participant.getLastName();
} else if (participant.getFirstName() != null) {
return participant.getFirstName();
} else if (participant.getLastName() != null) {
return participant.getLastName();
}
return "Unknown";
}

private byte[] finalizeTranscript() {
try {
return this.generatePdfTranscript();
} catch (IOException e) {
log.error("Error generating file: {}", e.getMessage());
throw CustomParameterizedException.singleParameterProblem(
String.format("Error generating transcript...  %n%s", e.getMessage()),
Status.BAD_REQUEST
);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}

private byte[] generatePdfTranscript() throws IOException, DocumentException {
if (ticketNumber != null) {
fileName = sanitizeFilename(ticketNumber + "_transcript.pdf");
} else {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
fileName = sanitizeFilename(customerName + "_" + LocalDateTime.now().format(formatter) + "_transcript.pdf");
}

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Document document = new Document(PageSize.A4, MARGIN_X, MARGIN_X, MARGIN_Y, MARGIN_Y);
PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream);

document.open();

PDDocument pdDocument = new PDDocument();
initializeFonts(pdDocument);

setupPdfHeader(document);
addTranscriptTitle(document);

for (Message message : messages) {
addMessage(document, writer, message);
}

document.close();
pdDocument.close();

return byteArrayOutputStream.toByteArray();
}

private void setupPdfHeader(Document document) throws DocumentException {
Font headerFont = new Font(Font.FontFamily.HELVETICA, FONT_SIZE, Font.BOLD);

Paragraph header = new Paragraph();
header.setAlignment(Element.ALIGN_LEFT);

if (ticketNumber != null) {
header.add(new Chunk("Ticket Number: " + ticketNumber + "\n", headerFont));
header.add(new Chunk("Date & Time Ticket Issued: " + issuedTime + "\n", headerFont));
header.add(new Chunk("Date & Time Ticket Closed: " + closedTime + "\n", headerFont));
} else {
header.add(new Chunk("No ticket issued\n", headerFont));
}

if (clientWhatsAppNumber != null) {
header.add(new Chunk("Service's WhatsApp number: " + clientWhatsAppNumber + "\n", headerFont));
}

if (customerWhatsAppNumber != null) {
header.add(new Chunk("Customer's WhatsApp number: " + customerWhatsAppNumber + "\n", headerFont));
}

header.add(new Chunk("Agent's Name & Surname: " + agentName + "\n", headerFont));
header.add(new Chunk("Customer's Name & Surname: " + customerName + "\n", headerFont));

PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell(header);
cell.setBorder(Rectangle.BOX);
cell.setPadding(10);
table.addCell(cell);

document.add(table);
document.add(Chunk.NEWLINE);
}

private void addTranscriptTitle(Document document) throws DocumentException {
Font titleFont = new Font(Font.FontFamily.HELVETICA, FONT_SIZE + 2, Font.BOLD);
Paragraph title = new Paragraph("Ticket Transcript:", titleFont);
title.setAlignment(Element.ALIGN_LEFT);
document.add(title);
document.add(Chunk.NEWLINE);
}

private void addMessage(Document document, PdfWriter writer, Message message) throws DocumentException, IOException {
String sender = message.getDirection().equals(Pl4ChatMessageDirection.OUTGOING) ? agentName : customerName;

if (message.getContentType().equals(Pl4ContentType.MEDIA)) {
addMediaMessage(document, writer, message, sender);
} else {
String messageText = sender + ": "  + message.getText();

PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);

PdfPCell cell = new PdfPCell();
cell.setPadding(10);
cell.setBorder(Rectangle.BOX);
cell.setBackgroundColor(message.getDirection().equals(Pl4ChatMessageDirection.OUTGOING) ?
new BaseColor(220, 220, 220) : new BaseColor(220, 248, 198));

Paragraph paragraph = new Paragraph();
addMixedTextToParagraph(paragraph, messageText);
cell.addElement(paragraph);

table.addCell(cell);
document.add(table);

addTimestamp(document, message);
}
}

private void addMediaMessage(Document document, PdfWriter writer, Message message, String sender) throws DocumentException {
String mediaURL = message.getMediaURL();
String linkText = message.getText() != null ? message.getText() : "View Media";
String senderText = sender + ": ";

PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);

PdfPCell cell = new PdfPCell();
cell.setPadding(10);
cell.setBorder(Rectangle.BOX);
cell.setBackgroundColor(message.getDirection().equals(Pl4ChatMessageDirection.OUTGOING) ?
new BaseColor(220, 220, 220) : new BaseColor(220, 248, 198));

Paragraph paragraph = new Paragraph();
paragraph.add(new Chunk(senderText, new Font(Font.FontFamily.HELVETICA, FONT_SIZE)));

Anchor anchor = new Anchor(linkText, new Font(Font.FontFamily.HELVETICA, FONT_SIZE, Font.UNDERLINE, BaseColor.BLUE));
anchor.setReference(mediaURL);
paragraph.add(anchor);

cell.addElement(paragraph);
table.addCell(cell);
document.add(table);

addTimestamp(document, message);
}

private void addTimestamp(Document document, Message message) throws DocumentException {
String timeString = formatDateTime(message.getCreatedTime());
Paragraph timestamp = new Paragraph(timeString, new Font(Font.FontFamily.HELVETICA, 8));
timestamp.setAlignment(Element.ALIGN_RIGHT);
document.add(timestamp);
document.add(Chunk.NEWLINE);
}

private String formatDateTime(LocalDateTime dateTime) {
return dateTime != null ? dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "N/A";
}

private void initializeFonts(PDDocument document) throws IOException {
fallbackFont = PDType1Font.HELVETICA;
try (InputStream emojiFontStream = getClass().getClassLoader().getResourceAsStream("static/NotoColorEmoji-Regular.ttf")) {
if (emojiFontStream == null) {
throw new FileNotFoundException("Emoji font file not found in classpath.");
}
emojiFont = PDType0Font.load(document, emojiFontStream);
}
}

private void addMixedTextToParagraph(Paragraph paragraph, String text) {
for (int i = 0; i < text.length(); i++) {
int codePoint = text.codePointAt(i);
String charString = new String(Character.toChars(codePoint));
Font font = Character.isSupplementaryCodePoint(codePoint) ? new Font(Font.FontFamily.UNDEFINED) : new Font(Font.FontFamily.HELVETICA);
paragraph.add(new Chunk(charString, font));

if (Character.isSupplementaryCodePoint(codePoint)) {
i++;
}
}
}

private List
 splitTextToLines(String text, float maxWidth) {
List processedParts = processText(text);
List lines = new ArrayList();

StringBuilder currentLine = new StringBuilder();
String currentStyle = "";

for (ProcessedPart part : processedParts) {
String[] words = part.text.split("\\s+");

for (String word : words) {
if (fitsInCurrentLine(currentLine, word, maxWidth)) {
appendWordToLine(currentLine, word);
} else {
addLineIfNotEmpty(lines, currentLine, currentStyle);
currentLine = new StringBuilder(word);
}
}

if (part.lineBreak >  0) {
addLineIfNotEmpty(lines, currentLine, currentStyle);
addLineBreak(lines, part.lineBreak);
}

currentStyle = part.style;
}

addLineIfNotEmpty(lines, currentLine, currentStyle);

return lines;
}

private boolean fitsInCurrentLine(StringBuilder currentLine, String word, float maxWidth) {
String testLine = currentLine.length() > 0 ? currentLine + " " + word : word;
return calculateWidth(testLine)  0) {
line.append(" ");
}
line.append(word);
}

private void addLineIfNotEmpty(List lines, StringBuilder line, String style) {
if (line.length() > 0) {
lines.add(new ProcessedPart(line.toString(), style, 0));
line.setLength(0);
}
}

private void addLineBreak(List lines, int lineBreak) {
lines.add(new ProcessedPart("", "", lineBreak));
}

private float calculateWidth(String text) {
float width = 0;
for (int i = 0; i < text.length(); i++) {
int codePoint = text.codePointAt(i);
PDFont currentFont = Character.isSupplementaryCodePoint(codePoint) ? emojiFont : fallbackFont;

try {
String charString = new String(Character.toChars(codePoint));
width += currentFont.getStringWidth(charString) / 1000 * FONT_SIZE;
} catch (IllegalArgumentException | IOException e) {
log.warn("Unable to calculate width for character: {} ({}).  Using fallback width.",
String.format("U+%04X", codePoint), new String(Character.toChars(codePoint)));
width += fallbackFont.getAverageFontWidth() / 1000 * FONT_SIZE;
}

if (Character.isSupplementaryCodePoint(codePoint)) {
i++;
}
}
return width;
}

public static class ProcessedPart {
String text;
String style;
int lineBreak;

public ProcessedPart(String text, String style, int lineBreak) {
this.text = text;
this.style = style;
this.lineBreak = lineBreak;
}

@Override
public String toString() {
return "ProcessedPart{" +
"text='" + text + '\'' +
", style='" + style + '\'' +
", lineBreak=" + lineBreak +
'}';
}
}

private List processText(String messageText) {
List partsList = new ArrayList();

String regex = "(.*?[/b]|[i].*?[/i]|.*?|.*?
||\\n)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(messageText);

int lastEnd = 0;
while (matcher.find()) {
if (matcher.start() > lastEnd) {
partsList.add(new ProcessedPart(messageText.substring(lastEnd, matcher.start()), NORMAL_FONT, 0));
}

String part = matcher.group();
if ("
".equals(part)) {
partsList.add(new ProcessedPart("", NORMAL_FONT, 1));
} else if ("\n".equals(part)) {
partsList.add(new ProcessedPart("", NORMAL_FONT, 1));
} else {
handleFormatters(partsList, part);
}

lastEnd = matcher.end();
}

if (lastEnd < messageText.length()) {
partsList.add(new ProcessedPart(messageText.substring(lastEnd), NORMAL_FONT, 0));
}

return partsList;
}

private void handleFormatters(List partsList, String part) {
String substring = part.substring(3, part.length() - 4);

if (part.startsWith("") && part.endsWith("
")) {
partsList.add(new ProcessedPart(substring, "bold", 0));
} else if (part.startsWith("") && part.endsWith("")) {
partsList.add(new ProcessedPart(substring, "italic", 0));
} else if (part.startsWith("") && part.endsWith("")) {
partsList.add(new ProcessedPart(substring, "strikethrough", 0));
} else if (part.startsWith("

Код: Выделить всё

") && part.endsWith("
")) {
partsList.add(new ProcessedPart(part.substring(6, part.length() - 7), "monospace", 0));
}
}

private String sanitizeFilename(String filename) {
// Remove or replace characters that are not allowed in filenames
return filename.replaceAll("[\\\\/:*?\"|]", "_");
}
}

Я пробовал отображать смайлы как они есть, но имя клиента перенастраивается без смайликов «Esphi N» вместо этого «🌹🦬🪶🐓Esphi N🤣😂», моя цель — отображать их такими, какие они есть, как для имени файла, так и для имени пользователя.


Подробнее здесь: https://stackoverflow.com/questions/790 ... -usernames
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»