PDFBox не может правильно сопоставитьсяJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 PDFBox не может правильно сопоставиться

Сообщение Anonymous »

Теперь это мой код для отображения и отображения всех страниц электронной книги в приложении JavaFx, и я знаю, что я не отображаю все возможные вещи, но то, что я отображаю, я не могу сделать так же, как это есть в электронной книге

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

    public void adicionarNovaTab(Ebook ebookSelecionado) {
try (PDDocument document = Loader.loadPDF(ebookSelecionado.getConteudo())) {
PDPageTree pages = document.getPages();
CustomTab customTab = new CustomTab(ebookSelecionado.getNome());

int pageNumber = 1;
ScrollPane scrollPane = new ScrollPane();

VBox vBox = new VBox();
vBox.setSpacing(20);
vBox.setMinWidth(Region.USE_COMPUTED_SIZE);
vBox.setMinHeight(Region.USE_COMPUTED_SIZE);
vBox.setMaxWidth(Region.USE_COMPUTED_SIZE);
vBox.setMaxHeight(Region.USE_COMPUTED_SIZE);
for (PDPage page : pages) {
Pane pane = new Pane();
Background background = new Background(new BackgroundFill(Paint.valueOf("WHITE"), null, null));
pane.setBackground(background);
double pageWidth = page.getMediaBox().getWidth();
double pageHeight = page.getMediaBox().getHeight();
pane.setPrefSize(pageWidth, pageHeight);
pane.setMinSize(pageWidth, pageHeight);
pane.setMaxSize(pageWidth, pageHeight);

List textoComCoordenadas = extrairTextoDaPagina(pageNumber, page, document);

textoComCoordenadas.forEach(texto -> {
Text text = new Text(String.valueOf(texto.getCaractere()));
text.setX(texto.getX());
text.setY(texto.getY());

if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(), texto.getFontSize());
text.setFont(font);
} else {
Font font = Font.font(texto.getFonte() != null && texto.getFonte().getNome() != null ? texto.getFonte().getNome() : "Arial",
texto.isBold() ? FontWeight.BOLD : FontWeight.NORMAL,
texto.isItalic() ? FontPosture.ITALIC : FontPosture.REGULAR,
texto.getFontSize());
text.setFont(font);
}

pane.getChildren().add(text);
});
vBox.getChildren().add(pane);
pageNumber++;

scrollPane.setContent(vBox);
scrollPane.setFitToWidth(true); // Ajusta a largura do conteúdo ao ScrollPane
scrollPane.setFitToHeight(true); // Ajusta a altura do conteúdo ao ScrollPane
customTab.setContent(scrollPane);

if (!tabPaneVisualizador.getTabs().contains(customTab)) {
tabPaneVisualizador.getTabs().add(customTab);
}
}

} catch (IOException e) {
throw new RuntimeException(e);
}
}

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

    private List extrairTextoDaPagina(int numeroDaPagina, PDPage page, PDDocument document) throws IOException {
List textosComCoordenadas = new ArrayList();

PDResources resources = page.getResources();
Iterable fontNames = resources.getFontNames();
fontNames.forEach(font -> {
try {
PDFont pdFont = resources.getFont(font);
String nomeFonte = pdFont.getName();
boolean temMesmoNome = fontesDosEbooks.stream().anyMatch(fonte -> fonte.getNome().equals(nomeFonte));

if (!temMesmoNome && pdFont.getFontDescriptor() != null && pdFont.getFontDescriptor().getFontFile() != null) {
COSInputStream cosInputStream = pdFont.getFontDescriptor().getFontFile().createInputStream();
FonteDoEbook fonte = FonteDoEbook.builder().nome(nomeFonte).inputStream(cosInputStream).build();
fontesDosEbooks.add(fonte);
System.out.println("Adicionado uma fonte: "  + nomeFonte);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});

PDFTextStripper textStripper = new PDFTextStripper() {
@Override
protected void writeString(String text, List textPositions) throws IOException {
for (int i = 0; i < textPositions.size(); i++) {
TextPosition textPosition = textPositions.get(i);
float x = textPosition.getXDirAdj();
float y = textPosition.getYDirAdj();
boolean italic = false;
boolean forceBold = false;
float fontSize = textPosition.getFontSize();
final String nomeDaFonte = textPositions.get(i).getFont().getName();

if (textPosition.getFont().getFontDescriptor() != null) {
italic = textPosition.getFont().getFontDescriptor().isItalic();
forceBold = textPosition.getFont().getFontDescriptor().isForceBold();
if (!italic && nomeDaFonte.toLowerCase().contains("-it")) {
italic = true;
}
if (!forceBold && nomeDaFonte.toLowerCase().contains("bold")) {
forceBold = true;
}
}

TextoComCoordenadas.TextoComCoordenadasBuilder textoComCoordenadasBuilder =
TextoComCoordenadas.builder()
.caractere(text.charAt(i))
.x(x)
.y(y)
.fontSize(fontSize)
.bold(forceBold)
.italic(italic);

Optional first = fontesDosEbooks.stream()
.filter(fonte ->  fonte.getNome().equals(nomeDaFonte)).findFirst();

if (first.isPresent())
textoComCoordenadasBuilder.fonte(first.get());
else {
FonteDoEbook fonte = FonteDoEbook.builder().nome(nomeDaFonte).build();
fontesDosEbooks.add(fonte);
}

textosComCoordenadas.add(textoComCoordenadasBuilder.build());
}
}
};
textStripper.setStartPage(numeroDaPagina);
textStripper.setEndPage(numeroDaPagina);
textStripper.getText(document);

return textosComCoordenadas;
}
Ещё раз говорю: я не говорю о вещах, которые сейчас не отображаю, таких как цвета и подчеркивания.
Я думаю, что это настоящая проблема это правильный интервал между словами и шрифтом, и я не знаю, почему, потому что я использую этот foreach, чтобы получить все шрифты из PDF-файла, которые добавляются в PDF, потому что это не стандартный шрифт:

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

package br.com.danielschiavo.livrariavirtual.util;

import lombok.*;

import java.io.InputStream;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(of = "nome")
public class FonteDoEbook {

private InputStream inputStream;

private String nome;
}

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

package br.com.danielschiavo.livrariavirtual.util;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class TextoComCoordenadas {

private char caractere;

private float x;

private float y;

private float fontSize;

private boolean bold;

private boolean italic;

private FonteDoEbook fonte;

}
Итак, предполагается, что нужно получить все эти шрифты, о которых я говорил, и этот foreach можно найти в этой книге, которую я показал в качестве примера имен следующих шрифтов:

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

CESPXI+NimbusSanL-Regu
JNISHD+MinionPro-It
ADEOBE+MinionPro-Bold
QFIOSQ+NimbusMonL-Regu
SHIDIU+MinionPro-Regular
F81
CESPXI+NimbusSanL-Regu
Шрифт F81 специально спамит на консоли примерно 100 раз:

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

05:48:46.158 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a99 (99) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a108 (108) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a97 (97) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a115 (115) in font F81
Электронная книга открыта в браузере
Электронная книга открыта в моем приложении
Я уже пробовал, вместо использования объект COS InputStream, используя новый ByteArrayInputStream (здесь байты), но это тоже не сработало
Я уже записываю байты одного шрифта, которые я получаю из функции PDFBox, в foreach, который я упомянутое выше, в файл ttf и успешно открыл файл в FontForge.
Я уже пытался установить шрифт в текстовом объекте с помощью этого метода:

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

if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(), texto.getFontSize());
text.setStyle("-fx-font-family: " + texto.getFonte().getNome() + "; -fx-font-size: " + texto.getFontSize() + ";");
вместо:

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

if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(),texto.getFontSize());
text.setFont(font);
но это тоже не сработало

Подробнее здесь: https://stackoverflow.com/questions/785 ... -correctly
Ответить

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

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

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

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

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